Search code examples
androidlistviewlistadapterlayoutparamsleaderboard

Changing width of individual items in a listview


So I've searched around for an answer or a possible solution to this problem for a couple weeks now and still haven't gotten any farther. I'm working on building an app that rewards users with points after certain things. One of the pages they can visit is a leader board based off of the friends the user has. I'm able to implement the leader board and print the users in order based off of their points, but can't implement a bar graph style look. Like So: https://i.sstatic.net/Qt8bY.jpg (Had to post a link because I can't paste a picture in here)

Here is what I've tried so far: 1. Adding a to xml and trying to getLayoutParams in the custom adapter then set the width, which didn't work. 2. using onDraw to draw a rectangle over top of the list item.

Here is my Leader board xml file (or close to it):

<LinearLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/leader_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="left|top"
        android:background="#00000000">

</LinearLayout>

My listview row xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frame"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <RelativeLayout
        android:id="@+id/bottom"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"> 

        <ImageView
             android:id="@+id/user_image"
             android:layout_width="40dp"
             android:layout_height="40dp"
             android:layout_alignParentLeft="true"
             android:layout_alignParentTop="true"
             android:layout_centerVertical="true"
             android:background="@drawable/ic_default_user"/>

         <TextView
             android:id="@+id/rank"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerVertical="true"
             android:paddingLeft="10dp"
             android:layout_toRightOf="@+id/user_image"/>

         <TextView
             android:id="@+id/user_name"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_centerVertical="true"
             android:paddingLeft="20dp"
             android:textSize="16sp"
             android:layout_toRightOf="@+id/rank"/>

         <TextView
             android:id="@+id/score"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_alignParentRight="true"
             android:layout_centerVertical="true"
             android:layout_toRightOf="@+id/user_name"
             android:gravity="right"
             android:paddingRight="15dp"/>

    </RelativeLayout>

</FrameLayout>

and my custom ArrayAdapter in my leaderboard class

public class LeaderAdapter extends ArrayAdapter<LeaderboardDM>{
    ArrayList<LeaderboardDM> leaders;
    int layoutResourceId;

    public LeaderAdapter(Context context, int layoutResourceId, ArrayList<LeaderboardDM> leaders){
        super(context, layoutResourceId, leaders);
        this.leaders = new ArrayList<LeaderboardDM>();
        this.leaders = leaders;
        this.layoutResourceId = layoutResourceId;
    }

    public View getView(int position, View convertView, ViewGroup parent){
        View v = convertView;
        ViewHolder viewHolder = null;
        if(v == null){
            v = getLayoutInflater().inflate(layoutResourceId, null, false);
            viewHolder = new ViewHolder();
            viewHolder.userImage = (ImageView) v.findViewById(R.id.user_image);
            viewHolder.rank = (TextView) v.findViewById(R.id.rank);
            viewHolder.userName = (TextView) v.findViewById(R.id.user_name);
            viewHolder.score = (TextView) v.findViewById(R.id.score);
            v.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) v.getTag();
        }
        LeaderboardDM lead = leaders.get(position);
        if(lead != null){
            //doesn't set user image yet
            viewHolder.userName.setText(lead.user);
            viewHolder.score.setText(String.valueOf(lead.points));
            viewHolder.rank.setText("#"+String.valueOf(position+1));

        }
        return v;
    }
    class ViewHolder{
        ImageView userImage;
        TextView rank, userName, score;

    }
}

and the leaderboardDM class

public class LeaderboardDM{
    public String user;
    public int points;
    public String profilePicUrl;

    public void setUserName(String user){
        this.user = user;
    }
    public String getUserName(){
        return user;
    }
    public void setPoints(int points){
        this.points = points;
    }
    public int getPoints(){
        return points;
    }
    public void setProfilePic(String url){
        this.profilePicUrl = url;
    }
    public String getProfilePicUrl(){
        return profilePicUrl;
    }
}

The list gets sorted through using a comparator and again prints in order of their score. If anyone has an idea on how to create something like this please help point me in the right direction.

Thanks!

Edit: Thanks to @Ridcully I was able to solve this issue. The solution worked perfectly for anyone in the future that may do this, was to create a custom progress bar and get the drawable from the resources then set the ProgressDrawable to that drawable. From there I would set the width by setProgress(int width).


Solution

  • You could use a RelativeLayout and put a ProgressBar (with customized drawable) in the back. This way you can set the width of the bar by a simple setProgress().