TrinityTuts

Understanding custom ListView using custom adapter

Last updated on January 1st, 2020 at 09:06 pm

Custom ListView is very useful for customizing view and make app interface more attractive. In this post i explain how to make custom adapter and how its work.

Adapter: Adapter is used to set view inside your ListView or Spinner etc.

1. Create new project in android studio.

2. Open activity_main.xml inside your res/layout folder and add ListView inside it.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">
 
    <ListView
        android:id="@+id/captureList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></ListView>
 
</RelativeLayout>

3.  Now create new view you want to inflate in your ListView. In this i have one ImageView for image two TextView one for Name and other for sub heading and also one CheckBox.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 
    <LinearLayout
        android:id="@+id/parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_margin="5dp"
        android:weightSum="3">
 
        <ImageView
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:id="@+id/pic"
            android:src="@drawable/ic_user" />
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_weight="2.9"
            android:layout_margin="5dp"
            android:paddingLeft="10dp"
            android:layout_gravity="center">
 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/name"
                android:text="User name"
                android:textSize="18dp" />
 
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:id="@+id/no"
                android:layout_marginTop="10dp"
                android:text="Phone no."
                android:textSize="18dp" />
 
        </LinearLayout>
 
        <LinearLayout
            android:layout_weight="0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="25dp"
            android:layout_gravity="right|center"
            android:gravity="center"
            android:visibility="visible"
            android:orientation="horizontal">
 
            <CheckBox
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:id="@+id/check" />
 
        </LinearLayout>
 
    </LinearLayout>
 
</LinearLayout>

4. Now before start creating custom adapter for your ListView create some getters and setters. I alway use getters and setters whenever i have to do this kind of thing. For more follow this. Why use getters and setters?

public class SelectUser {
    String name;
 
    public Bitmap getThumb() {
        return thumb;
    }
 
    public void setThumb(Bitmap thumb) {
        this.thumb = thumb;
    }
 
    Bitmap thumb;
 
    public String getPhone() {
        return phone;
    }
 
    public void setPhone(String phone) {
        this.phone = phone;
    }
 
    String phone;
 
    public Boolean getCheckedBox() {
        return checkedBox;
    }
 
    public void setCheckedBox(Boolean checkedBox) {
        this.checkedBox = checkedBox;
    }
 
    Boolean checkedBox = false;
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
}

5.  Now create your custom adapter

public class SelectUserAdapter extends BaseAdapter {
 
    public List<SelectUser> _data;
    Context _c;
    ViewHolder v;
 
    public SelectUserAdapter(List<SelectUser> selectUsers, Context context) {
        _data = selectUsers;
        _c = context;
    }
 
    @Override
    public int getCount() {
        return _data.size();
    }
 
    @Override
    public Object getItem(int i) {
        return _data.get(i);
    }
 
    @Override
    public long getItemId(int i) {
        return i;
    }
 
    @Override
    public View getView(int i, View convertView, ViewGroup viewGroup) {
        View view = convertView;
        final int position = i;
        if (view == null) {
            LayoutInflater li = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = li.inflate(R.layout.contact_info, null);
            
        } else {
            view = convertView;
        }
 
        v = new ViewHolder();
 
        v.parent = (LinearLayout) view.findViewById(R.id.parent);
        v.title = (TextView) view.findViewById(R.id.name);
        v.check = (CheckBox) view.findViewById(R.id.check);
        v.phone = (TextView) view.findViewById(R.id.no);
        v.imageView = (ImageView) view.findViewById(R.id.pic);
 
        final SelectUser data = (SelectUser) _data.get(i);
        v.title.setText(data.getName());
        v.check.setChecked(data.getCheckedBox());
        v.phone.setText(data.getPhone());
 
        // Set image if exists
        if (data.getThumb() != null) {
            v.imageView.setImageBitmap(data.getThumb());
        } else {
            v.imageView.setImageResource(R.drawable.ic_user);
        }
 
        // Set check box listener android
        v.check.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
 
                CheckBox checkBox = (CheckBox) view;
                if (checkBox.isChecked()) {
		data.setCheckedBox(true);
                } else {
                    data.setCheckedBox(false);
                }
		notifyDataSetChanged();
            }
        });
 
        view.setTag(data);
        return view;
    }

 
    static class ViewHolder {
        ImageView imageView;
        TextView title, phone;
        CheckBox check;
        LinearLayout parent;
    }
}

In this i pass my ArrayList and context through constructor. I extend  BaseAdapter in for my custom Adapter . In this user set all data in list we get and put it in view now when user click on check box {Check/Uncheck} we setCheckBox value to true/false and

notifyDataSetChanged();

The definition of notifyDataSetChanged in the Android‘s documentation is as folow

Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.

This is really very important thing to do when we deal with check box in ListView due to the nature of ListView. To know more about ListView please follow this link .

6. Now last step open your MainActivity.java and paste bellow code.

public class Guest_contact extends ActionBarActivity implements GetResponse, View.OnClickListener {
  
    ArrayList<SelectUser> selectUsers;
   
    // Contact List
    ListView listView; 
	SelectUserAdapter adapter;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.guest_contact);
 
        selectUsers = new ArrayList<SelectUser>();
        listView = (ListView) findViewById(R.id.contacts_list);
 
	// set data in adapter
	SelectUser selectUser = new SelectUser();
        selectUser.setThumb("Image bitmap");
        selectUser.setName("Aneh");
        selectUser.setPhone("123456780");
        selectUser.setCheckedBox(false);
        selectUsers.add(selectUser);
		
		
	SelectUser selectUser = new SelectUser();
        selectUser.setThumb("");
        selectUser.setName("Amit");
        selectUser.setPhone("1234567890");
        selectUser.setCheckedBox(false);
        selectUsers.add(selectUser);
 
        adapter = new SelectUserAdapter(selectUsers, Guest_contact.this);
        listView.setAdapter(adapter);
    }
}

That it. Now your Custom Listview is ready to use. You also create a custom adapter for your spinner like this.

🙂