Custom Listview in Android

Today we will learn how to create a custom designed listview in android which will be scrolling smoothly. So lets do it.

First take a listview in your xml layout and give a id.

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".activity.MainActivity">

        <ListView
            android:id="@+id/ll_list"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>
</layout>

If you dont know what is <layout> for, you can visit this link: to understand.

Then you have to design your own custom row like this:

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_width="match_parent"
                android:layout_height="100dp">
                <ImageView
                    android:id="@+id/iv_image"
                    android:layout_width="100dp"
                    android:layout_height="100dp" />
                <LinearLayout
                    android:padding="5dp"
                    android:gravity="center|start"
                    android:orientation="vertical"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">
                    <TextView
                        android:layout_margin="5dp"
                        android:textSize="18sp"
                        android:id="@+id/tv_item_name"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" />
                    <TextView
                        android:id="@+id/tv_item_name_secondary"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" />
                </LinearLayout>
            </LinearLayout>
    </LinearLayout>
</layout>

Now create 2 classes called ListviewAdapters and MainModel.Here is the code:

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import com.bumptech.glide.Glide;

import java.util.List;

import club.tushar.customlistview.R;
import club.tushar.customlistview.databinding.RowCustomItemBinding;
import club.tushar.customlistview.models.MainModel;

public class ListviewAdapters extends BaseAdapter {

    private Context context;
    private List<MainModel> dtos;

    public ListviewAdapters(Context context, List<MainModel> dtos) {
        this.context = context;
        this.dtos = dtos;
    }

    @Override
    public int getCount() {
        return dtos.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        Holder holder;

        if(convertView == null){
            holder = new Holder(context);
            convertView = holder.binding.getRoot();
            convertView.setTag(holder);
        }else {
            holder = (Holder) convertView.getTag();
        }

        holder.binding.tvItemName.setText(dtos.get(position).getName());
        holder.binding.tvItemNameSecondary.setText(dtos.get(position).getNameSecondary());

        Glide.with(context).load(dtos.get(position).getImageUrl())
                .into(holder.binding.ivImage);

        return convertView;
    }


    private class Holder{
        RowCustomItemBinding binding;
        Holder(Context context){
            binding = DataBindingUtil.inflate(LayoutInflater.from(context), R.layout.row_custom_item, null, true);
        }
    }
}
public class MainModel {
    private String imageUrl;
    private String name;
    private String nameSecondary;

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNameSecondary() {
        return nameSecondary;
    }

    public void setNameSecondary(String nameSecondary) {
        this.nameSecondary = nameSecondary;
    }
}

And initialize your MainActivity like this:

import android.databinding.DataBindingUtil;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import java.util.ArrayList;
import java.util.List;

import club.tushar.customlistview.R;
import club.tushar.customlistview.adapters.ListviewAdapters;
import club.tushar.customlistview.databinding.ActivityMainBinding;
import club.tushar.customlistview.models.MainModel;

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        
        
        List<MainModel> list = new ArrayList();

        //populating testing data
        for(int t = 0; t < 90; t++){
            MainModel model = new MainModel();
            model.setName("name " + t);
            model.setNameSecondary("name sec" + t);
            model.setImageUrl("https://media.istockphoto.com/photos/christmas-lights-defocused-background-bokeh-gold-blue-picture-id613518332?k=6&m=613518332&s=612x612&w=0&h=Own5MdgJXjNhFd0YUyED1UP3mQsHeNhfML9F-DQYdYw=");
            list.add(model);
        }

        binding.llList.setAdapter(new ListviewAdapters(this, list));


    }
}

Now build and run. You are done.

Please comment bellow if you are not clear enough.