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); } } |