Android ListView using Kotlin

Filed Under: Android

In this tutorial, we’ll implement ListView in our Android apps using Kotlin.

What is Android ListView?

ListView is a very common UI element in Android Applications. It is used to display a list of items separated by dividers that can be scrolled endlessly. It’s generally used to display a group of related items.

ListView XML Layout

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

ListView XML attributes

  • android:divider : Drawable or color to draw between list items.
  • android:divider : Drawable or color to draw between list items.
  • android:dividerHeight : Height of the divider.
  • android:entries : An array resource can be passed here to be displayed as a List.
  • android:footerDividersEnabled : When set to false, there will be no divider at the end of the ListView.
  • android:headerDividersEnabled : When set to false, there will be no divider at the top of the ListView
  • android:clickable: This makes the ListView rows clickable. If you’re setting the ListView from the Activity, setting this attribute is not neccessary
  • android:listSelector: Set the background color of the list view row when it is clicked.

We can populate entries in the ListView without any Java code by defining an array in the strings.xml file:

 <string-array name="Colors">
        <item name="color">Red</item>
        <item name="color">Orange</item>
        <item name="color">Yellow</item>
        <item name="color">Green</item>
        <item name="color">Blue</item>
        <item name="color">White</item>
        <item name="color">Black</item>
        <item name="color">Purple</item>
        <item name="color">Pink</item>
        <item name="color">Gray</item>
        <item name="color">Cyan Blue</item>
        <item name="color">Magenta</item>
    </string-array>

Now the ListView is populated in the layout as:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:entries="@array/Colors"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Setting the width to wrap_content wraps the ListView rows to its content.

android listview entries xml

Setting Selectors and Divider Color in ListView

Use the following ListView tag:

<ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="@color/colorPrimary"
        android:dividerHeight="1dp"
        android:entries="@array/Colors"
        android:listSelector="@android:color/holo_green_dark"
        android:clickable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

android listview entries xml click selector

The above code makes the ListView selectable. But to add logic on each ListView row click we need to use the Adapter.

ListView Adapter

A ListView class by itself cannot populate the entries. An Adapter is responsible for populating the data in the ListView. We have built-in adapter classes(like the one above) which come with a built-in layout for each row. We can create our own Custom Adapter classes as well.

The adapter comes with its own set of built-in methods. Following two are the most important ones:

  1. getView() : We can inflate our own layouts in the Adapter inside this method.
  2. notifyDataSetChanged() method on the adapter is called if the data has changed or if new data is available.

To set the adapter on the ListView, we use the method setAdapter().

Types of ListView Adapters

There are four main types of Adapters:

  1. BaseAdapter – As the name suggests this abstract is extended by all the other adapters. When creating a custom adapter using this as the parent class, you need to override all the methods mentioned above along with getCount(), getId() etc.
  2. ArrayAdapter – This populates the ListView with the array supplied. It is defined as:
    var arrayAdapter = ArrayAdapter<String>(context,layout,array);
    

    The first parameter is the context, followed by the layout resource for the list rows.
    The layout must have a TextView. The third parameter is the array.

    For the ArrayAdapter you need to override the getView() method only. getCount() isn’t necessary since ArrayAdapter calculates the size of the array on its own.

  3. ListAdapter – Unlike an ArrayAdapter, this is an interface. So it can be used only with concrete adapter classes. Concrete Adapter classes are ListActivity and ListFragment.
  4. SimpleCursorAdapter – This is used when the data needs to populated from a Database. In its constructor, we must specify the layout for each row and also the Cursor instance which contains the fields that need to be displayed.

ListView Kotlin Project Structure

android listview project structure

1. XML Layout Code

The code for the activity_main.xml layout is given below:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">

    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:entries="@array/Colors"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

2. Main Activity Kotlin Code

The code for the MainActivity.kt class is given below.

package net.androidly.androidlylistview

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import kotlinx.android.synthetic.main.activity_main.*
import org.jetbrains.anko.toast

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var colorArrays = resources.getStringArray(R.array.Colors)
        var arrayAdapter = ArrayAdapter<string>(this, android.R.layout.simple_list_item_1, colorArrays)

        listView.adapter = arrayAdapter

        listView.setOnItemClickListener { adapterView, view, position: Int, id: Long ->

            toast(colorArrays[position])
        }
    }
}

In the above code, we display a toast message. We arrived at that shorthand Toast function by adding the Anko commons dependency in our build.gradle.

resources.getStringArray(R.array.Colors) converts the string array stored in the resources file into a Kotlin Array.

android.R.layout.simple_list_item_1 is a built-in layout which hosts a TextView only.

setOnItemClickListener is the Kotlin function that gets triggered when any ListView row is clicked. Here we can implement our logic.

The four arguments inside the function are:

  • adapterView: The parent view where the selection happens. Its ListView here.
  • view: The selected view (row) within the ListView
  • position: The position of the row in the adapter. This is an Int.
  • id: The row id of the selected item. This is a Long.

Instead of retrieving the value using the array, we can get it from the adapterView as:

val selectedString = adapterView.getItemAtPosition(position) as String

getItemAtPosition returns the List View Row at that index. The row is a TextView in this case.

The output of the application in action is given below:

android listview output

We can change the default item press color by creating a selector drawable inside the drawable folder.

list_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@color/colorAccent" android:state_pressed="true"/>
    <item android:drawable="@android:color/transparent"/>

</selector>

Add the following attribute inside the ListView XML Tag:

android:listSelector="@drawable/list_selector"

android list view selector drawable

You can download the project from the below link.

Comments

  1. edmond.yun says:

    I have a question :: simple_list_item_checked can’t be supported by Kotlin…. I can’t find similar example to use the property….
    please help me to let me know your opinion. thankful for your support in advance.

    thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages