Custom ArrayAdapter with ListView in Android

In the previous article ArrayAdapter in Android with Example, it’s been discussed how the ArrayAdapter works and what are the data sources which can be attached to the ArrayAdapter with ListView. In this article, it’s been discussed how to implement custom ArrayAdapter with the ListView. Have a look at the following image in which a single view in the ArrayAdapter can be customized.
Steps to Implement the Custom ArrayAdapter
Step 1: Create an Empty Activity project
- Create an Empty Activity Android studio project. Refer to Android | How to Create/Start a New Project in Android Studio?
 - And make sure to select the programming as Java.
 
Step 2: Working with the activity_main.xml
- In the activity_main.xml file, the root view is ListView. Invoke the following code into the activity_main.xml file and mention the appropriate ID for the ListView.
 
XML
<?xml version="1.0" encoding="utf-8"?><ListView     android:id="@+id/listView"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity"></ListView> | 
Step 3: Creating a custom View for ListView
- Under layout, the folder creates a layout as custom_list_view.xml and invokes the following code.
 
XML
<?xml version="1.0" encoding="utf-8"?><LinearLayout     android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    tools:ignore="UselessParent">      <ImageView        android:id="@+id/imageView"        android:layout_width="84dp"        android:layout_height="84dp"        android:padding="16dp"        tools:ignore="ContentDescription" />      <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center_vertical"        android:orientation="vertical">          <TextView            android:id="@+id/textView1"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginTop="16dp"            android:gravity="bottom|left"            android:textColor="@android:color/black"            android:textSize="18sp"            android:textStyle="bold"            tools:ignore="RtlHardcoded" />          <TextView            android:id="@+id/textView2"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginBottom="16dp"            android:gravity="top|left"            android:textColor="@android:color/black"            android:textSize="14sp"            tools:ignore="RtlHardcoded" />      </LinearLayout>  </LinearLayout> | 
- For every single item in the ListView this layout creates the following view for every single item in the array adapter.
 
Step 4: Create a custom class for custom layout
- By creating this custom class we invoke the getter and setter manually for the custom_list_view layout.
 - Create a custom class called NumbersView under the package folder of the Application.
 - And invoke the following code.
 
Java
public class NumbersView {      // the resource ID for the imageView    private int ivNumbersImageId;      // TextView 1    private String mNumberInDigit;      // TextView 1    private String mNumbersInText;      // create constructor to set the values for all the parameters of the each single view    public NumbersView(int NumbersImageId, String NumbersInDigit, String NumbersInText) {        ivNumbersImageId = NumbersImageId;        mNumberInDigit = NumbersInDigit;        mNumbersInText = NumbersInText;    }      // getter method for returning the ID of the imageview    public int getNumbersImageId() {        return ivNumbersImageId;    }      // getter method for returning the ID of the TextView 1    public String getNumberInDigit() {        return mNumberInDigit;    }      // getter method for returning the ID of the TextView 2    public String getNumbersInText() {        return mNumbersInText;    }} | 
Step 5: Now create a custom ArrayAdapter class of the type NumbersView
- Under the same package name, create a NumbersViewAdapter.java class of the type NumbersView which extends the ArrayAdapter class.
 - And invoke the following code inside the NumbersViewAdapter.java file. Comments are added for better understanding.
 
Java
import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ImageView;import android.widget.TextView;import androidx.annotation.NonNull;import androidx.annotation.Nullable;import java.util.ArrayList;  public class NumbersViewAdapter extends ArrayAdapter<NumbersView> {      // invoke the suitable constructor of the ArrayAdapter class    public NumbersViewAdapter(@NonNull Context context, ArrayList<NumbersView> arrayList) {                  // pass the context and arrayList for the super           // constructor of the ArrayAdapter class        super(context, 0, arrayList);    }      @NonNull    @Override    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {          // convertView which is recyclable view        View currentItemView = convertView;          // of the recyclable view is null then inflate the custom layout for the same        if (currentItemView == null) {            currentItemView = LayoutInflater.from(getContext()).inflate(R.layout.custom_list_view, parent, false);        }          // get the position of the view from the ArrayAdapter        NumbersView currentNumberPosition = getItem(position);          // then according to the position of the view assign the desired image for the same        ImageView numbersImage = currentItemView.findViewById(R.id.imageView);        assert currentNumberPosition != null;        numbersImage.setImageResource(currentNumberPosition.getNumbersImageId());          // then according to the position of the view assign the desired TextView 1 for the same        TextView textView1 = currentItemView.findViewById(R.id.textView1);        textView1.setText(currentNumberPosition.getNumberInDigit());          // then according to the position of the view assign the desired TextView 2 for the same        TextView textView2 = currentItemView.findViewById(R.id.textView2);        textView2.setText(currentNumberPosition.getNumbersInText());          // then return the recyclable view        return currentItemView;    }} | 
Step 6: Working with the MainActivity.java file
- In this case, there is a need to create a custom ArrayList of all the items that are Image for ImageView, Text for TextView 1, Text for TextView 2.
 
Java
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.widget.ListView;import java.util.ArrayList;  public class MainActivity extends AppCompatActivity {      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);          // create a arraylist of the type NumbersView        final ArrayList<NumbersView> arrayList = new ArrayList<NumbersView>();          // add all the values from 1 to 15 to the arrayList        // the items are of the type NumbersView        arrayList.add(new NumbersView(R.drawable.geeks_logo, "1", "One"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "2", "Two"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "3", "Three"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "4", "Four"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "5", "Five"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "6", "Six"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "7", "Seven"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "8", "Eight"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "9", "Nine"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "10", "Ten"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "11", "Eleven"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "12", "Twelve"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "13", "Thirteen"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "14", "Fourteen"));        arrayList.add(new NumbersView(R.drawable.geeks_logo, "15", "Fifteen"));          // Now create the instance of the NumebrsViewAdapter and pass           // the context and arrayList created above        NumbersViewAdapter numbersArrayAdapter = new NumbersViewAdapter(this, arrayList);          // create the instance of the ListView to set the numbersViewAdapter        ListView numbersListView = findViewById(R.id.listView);          // set the numbersViewAdapter for ListView        numbersListView.setAdapter(numbersArrayAdapter);    }} | 
				
					



