Kotlin ListView with custom BaseAdapter and API integration

Alex Schnabl
3 min readApr 21, 2021

Create Custom ListView with BaseAdapter

ListView Layout (‘res/layouts/layout_list_view.xml’)

This is the base Layout of what will later fill the ListView with Items.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>

<TextView
android:id="@+id/text_view_item_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="#FF000000"
/>

<TextView
android:id="@+id/text_view_item_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

</LinearLayout>

Main Layout (‘res/layouts/activity_main.xml’)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>

<ListView
android:id="@+id/listy"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

Item.kt Class

Item Objects will be the used to fill up the List with Data.

class Item(val itemName: String, val itemDescription: String) {  
override fun toString(): String {
return this.itemName
}
}

Adapter.kt Class

This implements the Adapter Interface (BaseAdapter) so that we can access and edit our ListView and fill it with our own custom Item Objects.

class CustomListAdapter(context: Context, items: ArrayList<Item>) : BaseAdapter() {  
private val context: Context
private val items: ArrayList<Item>

override fun getCount(): Int {
return items.size //returns total of items in the list
}

override fun getItem(position: Int): Any {
return items[position]
}

override fun getItemId(position: Int): Long {
return position.toLong()
}

override fun getView(position: Int, convertView: View?, parent:ViewGroup?):
View? {
var convertView: View? = convertView
if (convertView == null) {
convertView = LayoutInflater.from(context)
.inflate(R.layout.layout_list_view, parent, false)
}
val currentItem = getItem(position) as Item val textViewItemName = convertView
?.findViewById(R.id.text_view_item_name) as TextView
val textViewItemDescription = convertView
?.findViewById(R.id.text_view_item_description) as TextView
textViewItemName.text = currentItem.itemName
textViewItemDescription.text = currentItem.itemDescription
return convertView
}
init {
this.context = context
this.items = items
}
}

ListView Example Usage in MainActivity.kt

val data = generateItems() // calls function to get items listval adapter = CustomListAdapter(this@MainActivity, data)val itemsListView: ListView = findViewById<View>(R.id.listy) as ListView  
itemsListView.setAdapter(adapter)
// OnClick Event that will display the Name of the Item in a toast
itemsListView.setOnItemClickListener { parent, view, position, id ->
val element = adapter.getItem(position)
toast(element.toString())
}

Get Random Names from API

randommer.io is an API for random Data. Creating an account is free and the requests are simple with short responses.

This is an example request to get a random first- and last name:

curl -X GET "https://randommer.io/api/Name?nameType=fullname&quantity=1" -H  "accept: */*" -H  "X-Api-Key: {YOU_API_KEY}"

Make a Request to the API

To make requests in Kotlin we will use OkHttp.

Install OkHttp

build.gradle:

dependencies {
//...
implementation 'com.squareup.okhttp3:okhttp:3.8.1'
}

AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />

Get API Data

To get data from our API we will create a function which gets a certain number of Names, parses the request result and returns it as a List of Strings.

In MainActivity.kt:

fun getNamesData(num: Int) : List<String> {  
val apiUrlFullName = "https://randommer.io/api/Name?nameType=fullname&quantity=" + num

val request = Request.Builder()
.url(apiUrlFullName)
.header("accept", "*/*")
.header("X-Api-Key", "{YOU_API_KEY}")
.build()

val response = client.newCall(request).execute()

return response.body()?.string()?.replace("[", "")
?.replace("]", "")
?.replace("\"","")
?.split(",")!!
}

Async Request and Display Result in ListView

To make a requests in an application it is generally required to do it async so that it wont block the main thread. For that reason we will use Anko for Kotlin which makes it fairly easy.

Install Anko

build.gradle:

dependencies {
//...
implementation 'org.jetbrains.anko:anko-common:0.9'
}

Make async Request and display Result in ListView

To finish the app up the final challenge is to implement and execute an async request and display the received Data in the ListView.

In MainActivity.kt:

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

doAsync {
// get Data from API
val namesData = getNamesData(50)
val listy = ArrayList<Item>()
namesData.forEach {
listy.add(Item(it, "Just a regular Person..."))
}
uiThread {
// instantiate the custom list adapter
val adapter = CustomListAdapter(this@MainActivity, listy)
// get the ListView and attach the adapter
val itemsListView: ListView = findViewById<View>(R.id.listy) as ListView
itemsListView.setAdapter(adapter)
itemsListView.setOnItemClickListener { parent, view, position, id ->
val element = adapter.getItem(position)
toast(element.toString())
}
}
}
}

Conclusion

As you can see it is fairly easy to create an app in Kotlin that receives and displays data from an API. This is meant to help everyone who wants a quick and easy way to communicate with an API.

--

--