[Tutorial] How to implement a custom listview adapter in Android Studio

Listciews are likely among the most used Android layout elements. They can be used to display results of a query, communication between one or more users, filesystems or any number of other things.

While simple listviews containing one or two textviews per element are functional for basic applications, as your application grows in complexity they become lacking. Perhaps you’d like to display a photo within the list object, or perhaps more textviews, or any number of other things.

In that situation you need a custom listview adapter, which is actually very simple to implement.

The first thing you’ll want to do is design a single element of your listview as a layout file. To do so simply add a new layout file and design a single row of your list. You should probably encapsulate everything within a frame or relative layout which will use height wrap_content and design so that your list row object does not grow to unweildly heights.

For example, here is a listview object which contains a photo and several textviews:

 

List Element

And in code:

<?xml version=”1.0″ encoding=”utf-8″?>

<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”vertical” android:layout_width=”match_parent”
android:layout_height=”match_parent”>

<RelativeLayout
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:layout_gravity=”center_horizontal”
android:background=”@drawable/bck”>

<RelativeLayout
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:background=”@android:color/background_light”
android:layout_marginLeft=”5dp”
android:layout_marginTop=”5dp”
android:layout_marginRight=”5dp”
android:layout_marginBottom=”10dp”
android:padding=”5dp”>

<ImageView
android:layout_width=”60dp”
android:layout_height=”60dp”
android:id=”@+id/imageView”
android:background=”@android:color/holo_red_dark”
android:layout_marginRight=”10dp” />

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Video Title”
android:id=”@+id/textView”
android:layout_alignTop=”@+id/imageView”
android:layout_toEndOf=”@+id/imageView”
android:textSize=”26dp” />

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Video Group”
android:id=”@+id/textView2″
android:layout_alignBottom=”@+id/imageView”
android:layout_toEndOf=”@+id/imageView”
android:textSize=”20dp” />

<TextView
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:text=”Uploaded Date/Time”
android:id=”@+id/textView3″
android:layout_alignParentEnd=”true”
android:textSize=”16dp”
android:layout_alignBottom=”@+id/textView2″ />

<FrameLayout
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
android:layout_below=”@+id/textView3″
android:layout_marginLeft=”5dp”
android:layout_marginTop=”5dp”
android:layout_marginRight=”5dp”>

</FrameLayout>

</RelativeLayout>
</RelativeLayout>
</LinearLayout>

 

Let’s assume¬†we’ve called this file “list_element.xml”. Now we proceed to the actual adapter which allows us to use it in a listview.

Essentially we’re writing our own adapter class. Therefore, whatever we call it, it must extend BaseAdapter.

From there Android Studio (or Eclipse) will autogenerate four functions for you: getCount, getItem, getItemId and getView. We need to overload all but getItemId.

At this point you should have some data structure the list is pulling from. Let’s call it “data”.

For getCount simply return data.size().

For getItem simply return data.get(arg0) (or however else you would get that position in whatever structure you are using).

getView is the slightly tricky one where you actually make the custom layout work for you. No matter what you’ll need this at the head of the function:

if(arg1==null){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
arg1 = inflater.inflate(R.layout.list_element, arg2, false);
}

Where “list_element” should be the name of your layout file. This simply ensures that the list element exists so we don’t get NullPointerExceptions.

Now you simply create TextView, ImageView, Button, etc objects to reference the objects in the layout file, but with one very important distinction: They must use arg1.findViewByID rather than simply findViewByID. Should you not prepend the “arg1.”, you can expect your list to behave erratically, recycling¬†the data in elements while they are still visible during scrolling.

Once you’re done there just create a new object of your custom adapter class and use listview.setAdapter, and that’s it! You may experience some difficulty with certain types of layout objects, such as WebViews, and you would be best off going to Stack Overflow for help with such specifics, but this is the general gist of how to use custom layout adapters for ListViews.