GridView Using Custom ArrayAdapter in Android with Example
Last Updated :
12 Aug, 2024
This article will be building an application to demonstrate the use of CustomArrayAdapters in GridView. GridViews are view containers that display views in two-dimensional (rows and columns) they are used in my android applications one simple example would be the gallery app. The adapter connects the UI elements with the data source, It helps populate data with us taking care of it. e.g when the user is scrolling through a gallery app the GridView is automatically populated without specifying anything.
There are different Adapters to name a few:
This article will be covering the Custom ArrayAdapter.
Why use a Custom ArrayAdapter?
Android already provides the implementation for an ArrayAdapter, which can be used with just a single line demonstrated below. They are used when Whenever we have a list of single items we can use ArrayAdapter. For instance, a list of phone contacts, countries, or names. Below is the syntax of the ArrayAdapter used for displaying text data.
Syntax:
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
Parameters:
- Context: is the application context being used
- resource: The second parameter is the resource id used to set the layout(xml file).
- textViewResourceId: Id of the TextView element where the data will be displayed
- objects: are the data elements stored in an array.
The problem with or limitation of this method is we cannot use complex layouts eg. Imagine we were building an app like Netflix or prime where each element is made up of many elements eg an ImageView, TextView, etc. Such complex views are not possible with the simple implementation of the ArrayAdapter for this we need to create our custom Adapter by extending the ArrayAdapter class. The following code shows the structure of the Custom ArrayAdapter.
Java
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import java.util.List;
public class CustomAdapter extends ArrayAdapter {
public CustomAdapter(Context context, int resource,
List objects)
{
super(context, resource, objects);
}
@Override public int getCount()
{
return super.getCount();
}
@Override
public View getView(int position, View convertView,
ViewGroup parent)
{
return super.getView(position, convertView, parent);
}
}
Kotlin
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
class CustomAdapter(context: Context?, resource: Int, objects: List<*>?) : ArrayAdapter<Any?>(context!!, resource, objects!!) {
override fun getCount(): Int {
return super.getCount()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
return super.getView(position, convertView, parent)
}
}
The two important methods used are:
- getCount(): returns the number of data elements present in the List.
- getView(): this is the important method where will be initializing and returning the custom view.
Example
A sample GIF is given below to get an idea about what we are going to do in this article. We are going to implement this project using both Java and Kotlin Programming Language for Android.
Step by Step Implementation
Step 1: Create a New Project in Android Studio
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. The code for that has been given in both Java and Kotlin Programming Language for Android.
Step 2: Working with the XML Files
Next, go to the activity_main.xml file, which represents the UI of the project. Below is the code for the activity_main.xml file. Comments are added inside the code to understand the code in more detail.
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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=".MainActivity">
<GridView
android:id="@+id/grid_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Creating a new layout XML file
Creating a new file named custom_view.xml in the same folder as the activity_main.xml file. This Custom View will host an ImageView and a TextView.
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:textAlignment="center" />
</LinearLayout>

Step 3: Working with the Java/Kotlin Files
Now to hold the info of our custom view we need to create a getter setter class. We can do things without this just using two arrays one for images and the other for text but what if we want to modify your view to add a Button? Then will again need a third array. Hence a class that holds the custom view is a more flexible option. Create the class In the same folder as the MainActivity create a new class called items. Below is the code for the items file.
Java
public class items {
private int image_id;
private String text;
public int getImage_id() {
return image_id;
}
public void setImage_id(int image_id) {
this.image_id = image_id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
items(int img, String text) {
image_id = img;
this.text = text;
}
}
Kotlin
class items internal constructor(private var image_id: Int, private var text: String) {
fun getImage_id(): Int {
return image_id
}
fun setImage_id(image_id: Int) {
this.image_id = image_id
}
fun getText(): String {
return text
}
fun setText(text: String) {
this.text = text
}
fun items(img: Int, text: String) {
image_id = img
this.text = text
}
}
Note: For an image, we store the id of the image and not the image.
Step 4: Implementing the CustomAdapter class
Create a new class classed as CustomAdapter in the same folder as items. The main method of the Adapter is the getView().
Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View v = convertView;
if (v == null) {
// getting reference to the main layout and initializing
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(custom_layout_id, null);
}
// initializing the imageview and textview and setting data
ImageView imageView = v.findViewById(R.id.imageView);
TextView textView = v.findViewById(R.id.textView);
// get the item using the position param
items item = items_list.get(position);
imageView.setImageResource(item.getImage_id());
textView.setText(item.getText());
return v;
}
Kotlin
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var v = convertView
if (v == null) {
// getting reference to the main layout and initializing
val inflater = getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
v = inflater.inflate(custom_layout_id, null)
}
// initializing the imageview and textview and setting data
val imageView = v!!.findViewById<ImageView>(R.id.imageView)
val textView = v.findViewById<TextView>(R.id.textView)
// get the item using the position param
val item: items = items_list.get(position)
imageView.setImageResource(item.getImage_id())
textView.setText(item.getText())
return v
}
public View inflate (int resource,ViewGroup root)
Inflate a new view hierarchy from the specified xml resource. Throws InflateException if there is an error.
resource int: ID for an XML layout resource to load (e.g., R.layout.main_page)
root ViewGroup: Optional view to be the parent of the generated hierarchy. This value may be null.
This method first parses out the custom_view.xml file using the inflate() method. This method is quite computationally expensive and should be used only when needed eg. when the adapter has to populate new items when the user reaches the end of the screen. After getting the reference of the view we then initialize the image view and text view from the custom_view.xml file set the data and return the view. Below is the complete code for the CustomAdapter file. Comments are added inside the code to understand the code in more detail.
Java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class CustomAdapter extends ArrayAdapter<items> {
List<items> items_list;
int custom_layout_id;
public CustomAdapter(@NonNull Context context, int resource, @NonNull List<items> objects) {
super(context, resource, objects);
items_list = objects;
custom_layout_id = resource;
}
@Override public int getCount() {
return items_list.size();
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View v = convertView;
if (v == null) {
// getting reference to the main layout and initializing
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(custom_layout_id, null);
}
// initializing the imageview and textview and setting data
ImageView imageView = v.findViewById(R.id.imageView);
TextView textView = v.findViewById(R.id.textView);
// get the item using the position param
items item = items_list.get(position);
imageView.setImageResource(item.getImage_id());
textView.setText(item.getText());
return v;
}
}
Kotlin
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
class CustomAdapter(context: Context, resource: Int, objects: List<items>) : ArrayAdapter<items?>(context, resource, objects) {
init {
items_list = objects
custom_layout_id = resource
}
private var items_list: List<items>
private var custom_layout_id: Int
override fun getCount(): Int {
return items_list.size
}
fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
var v = convertView
if (v == null) {
// getting reference to the main layout and initializing
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
v = inflater.inflate(custom_layout_id, null)
}
// initializing the imageview and textview and setting data
val imageView = v!!.findViewById<ImageView>(R.id.imageView)
val textView = v.findViewById<TextView>(R.id.textView)
// get the item using the position param
val item: items = items_list[position]
imageView.setImageResource(item.getImage_id())
textView.setText(item.getText())
return v
}
}
Step 5: Working with the MainActivity File
Go to the MainActivity File and refer to the following code. Below is the code for the MainActivity File. Comments are added inside the code to understand the code in more detail. For the images, here we have used android studio icons. The images are present in the res/drawable folder. Should look like this
Java
import android.os.Bundle;
import android.widget.GridView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<items> itemsList = new ArrayList<>();
itemsList.add(new items(R.drawable.android_1, "image_1"));
itemsList.add(new items(R.drawable.android_2, "image_2"));
itemsList.add(new items(R.drawable.android_3, "image_3"));
itemsList.add(new items(R.drawable.android_4, "image_4"));
itemsList.add(new items(R.drawable.android_5, "image_5"));
itemsList.add(new items(R.drawable.android_1, "image_6"));
itemsList.add(new items(R.drawable.android_2, "image_7"));
itemsList.add(new items(R.drawable.android_3, "image_8"));
itemsList.add(new items(R.drawable.android_4, "image_9"));
itemsList.add(new items(R.drawable.android_5, "image_10"));
GridView gridView = findViewById(R.id.grid_view);
CustomAdapter customAdapter = new CustomAdapter(this, R.layout.custom_view, itemsList);
gridView.setAdapter(customAdapter);
}
}
Kotlin
import android.os.Bundle
import android.widget.GridView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val itemsList: List<items> = ArrayList<Any>()
itemsList.add(items(R.drawable.android_1, "image_1"))
itemsList.add(items(R.drawable.android_2, "image_2"))
itemsList.add(items(R.drawable.android_3, "image_3"))
itemsList.add(items(R.drawable.android_4, "image_4"))
itemsList.add(items(R.drawable.android_5, "image_5"))
itemsList.add(items(R.drawable.android_1, "image_6"))
itemsList.add(items(R.drawable.android_2, "image_7"))
itemsList.add(items(R.drawable.android_3, "image_8"))
itemsList.add(items(R.drawable.android_4, "image_9"))
itemsList.add(items(R.drawable.android_5, "image_10"))
val gridView = findViewById<GridView>(R.id.grid_view)
val customAdapter = CustomAdapter(this, R.layout.custom_view, itemsList)
gridView.adapter = customAdapter
}
}

Final Project Structure

Output:
Similar Reads
Java Tutorial
Java is a high-level, object-oriented programming language used to build applications across platformsâfrom web and mobile apps to enterprise software. It is known for its Write Once, Run Anywhere capability, meaning code written in Java can run on any device that supports the Java Virtual Machine (
11 min read
Java Interview Questions and Answers
Java is one of the most popular programming languages in the world, known for its versatility, portability, and wide range of applications. Java is the most used language in top companies such as Uber, Airbnb, Google, Netflix, Instagram, Spotify, Amazon, and many more because of its features and per
15+ min read
Java OOP(Object Oriented Programming) Concepts
Java Object-Oriented Programming (OOPs) is a fundamental concept in Java that every developer must understand. It allows developers to structure code using classes and objects, making it more modular, reusable, and scalable. The core idea of OOPs is to bind data and the functions that operate on it,
13 min read
Arrays in Java
Arrays in Java are one of the most fundamental data structures that allow us to store multiple values of the same type in a single variable. They are useful for storing and managing collections of data. Arrays in Java are objects, which makes them work differently from arrays in C/C++ in terms of me
15+ min read
Inheritance in Java
Java Inheritance is a fundamental concept in OOP(Object-Oriented Programming). It is the mechanism in Java by which one class is allowed to inherit the features(fields and methods) of another class. In Java, Inheritance means creating new classes based on existing ones. A class that inherits from an
14 min read
Java Exception Handling
Exception handling in Java allows developers to manage runtime errors effectively by using mechanisms like try-catch block, finally block, throwing Exceptions, Custom Exception handling, etc. An Exception is an unwanted or unexpected event that occurs during the execution of a program (i.e., at runt
10 min read
Collections in Java
Any group of individual objects that are represented as a single unit is known as a Java Collection of Objects. In Java, a separate framework named the "Collection Framework" has been defined in JDK 1.2 which holds all the Java Collection Classes and Interface in it. In Java, the Collection interfac
15+ min read
Java Interface
An Interface in Java programming language is defined as an abstract type used to specify the behaviour of a class. An interface in Java is a blueprint of a behaviour. A Java interface contains static constants and abstract methods. Key Properties of Interface: The interface in Java is a mechanism to
13 min read
Polymorphism in Java
Polymorphism in Java is one of the core concepts in object-oriented programming (OOP) that allows objects to behave differently based on their specific class type. The word polymorphism means having many forms, and it comes from the Greek words poly (many) and morph (forms), this means one entity ca
7 min read
Java Programs - Java Programming Examples
In this article, we will learn and prepare for Interviews using Java Programming Examples. From basic Java programs like the Fibonacci series, Prime numbers, Factorial numbers, and Palindrome numbers to advanced Java programs. Java is one of the most popular programming languages today because of it
8 min read