Friday, April 24, 2020

ListView Section Header Kotlin Android Example

We will make listview Group by Header means that listview items will be sorted by the header.
Section header means that a header among listview items to sort them with particular category.
For example, you are making listview with various names of counties. We can categorize countries by their continents.

Step 1. View Layout Files

First of all, make a new project in the android studio with empty activity and kotlin as the main programming language.
ListView Section Header Kotlin Android Example

For this, we need to create two different layout files : one for header and another for normal row.
So make two xml files res->layout directory. Name of first file should be lv_child.xml and second file should have the name like lv_header.xml
Add the below source code in lv_child.xml file.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="20dp"
        android:background="#e9771f"
        android:textColor="#ffffff"
        android:textSize="40sp"
        android:id="@+id/tvChild"
        android:text="Hello"/>

</android.support.constraint.ConstraintLayout>
Following is the source block for lv_header.xml
<?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">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="20dp"
        android:background="#e91fce"
        android:textColor="#13cac7"
        android:textSize="40sp"
        android:id="@+id/tvVehicle"
        android:text="Hello"/>

</LinearLayout>
Similar to the child layout, above file will generate the layout structure for the header row.
Step 2. Two Model Classes For Header and Child rows
Make a new kotlin class and give it a name like HeaderModel.kt
Write down the following lines in HeaderModel.kt
class HeaderModel : MainActivity.ListItem {

    private lateinit var name : String

    fun setheader(header: String) {
        this.name = header
    }

    override
    fun isHeader () : Boolean {
        return true
    }

    override
    fun getName(): String {
        return name
    }
}
Below is the coding writings for ChildModel.kt file.
class ChildModel : MainActivity.ListItem {

    private lateinit var name: String

    override
    fun isHeader () : Boolean {
        return false
    }

    override
    fun getName(): String {
        return name
    }

    fun setChild(child: String) {
        this.name = child
    }
}
Step 3. Perfect Adapter Class
We need to create adapter class which will help us to maintain data structure in list view.
Make a new Kotlin class with the name like CustomeAdapter.kt and write the following lines in it
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView
import java.util.ArrayList

class CustomeAdapter(private val context: Context, private val listItemArrayList: ArrayList<MainActivity.ListItem>) :
    BaseAdapter() {

    override fun getViewTypeCount(): Int {
        return count
    }

    override fun getItemViewType(position: Int): Int {

        return position
    }

    override fun getCount(): Int {
        return listItemArrayList.size
    }

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

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

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var convertView = convertView
        val holder: ViewHolder

        if (convertView == null) {
            holder = ViewHolder()
            val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

            if (listItemArrayList[position].isHeader()) {
                convertView = inflater.inflate(R.layout.lv_header, null, true)
                holder.tvLabel = convertView!!.findViewById(R.id.tvVehicle) as TextView
            } else {
                convertView = inflater.inflate(R.layout.lv_child, null, true)
                holder.tvLabel = convertView!!.findViewById(R.id.tvChild) as TextView
            }

            convertView.tag = holder
        } else {
            // the getTag returns the viewHolder object set as a tag to the view
            holder = convertView.tag as ViewHolder
        }

        holder.tvLabel!!.text = listItemArrayList[position].getName()

        return convertView
    }

    private inner class ViewHolder {

        var tvLabel: TextView? = null

    }

}
Step 4. Last Code For Main Files
Now we have reached to the final step of this tutorial.
You should have two main file activity_main.xml and MainActivity.kt
In your activity_main.xml file, add the following lines
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
        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"
        tools:context=".MainActivity">

    <ListView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:id="@+id/listView"/>

</android.support.constraint.ConstraintLayout>
Now in MainActivity.kt file, write the below coding lines
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.ListView
import java.lang.String
import java.util.ArrayList

class MainActivity : AppCompatActivity() {

    private var lv: ListView? = null
    private var customeAdapter: CustomeAdapter? = null

    private val vehicleTypes = arrayOf("Cars", "Bikes", "Air Crafts", "Old Vehicles")

    private var listItemArrayList: ArrayList<ListItem>? = null

    private val childnames = arrayOf(
        "Range Rover",
        "Lamborghini",
        "Rolls Royce",
        "Ferrari",
        "Harley davidson",
        "Ducati",
        "BMW",
        "Honda",
        "Boeing",
        "Airbus",
        "Royal Air",
        "Space X",
        "Horse",
        "Elephant",
        "Camel",
        "Donkey"
    )

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

        lv = findViewById(R.id.listView) as ListView

        listItemArrayList = ArrayList()
        populateList()

        customeAdapter = CustomeAdapter(this, listItemArrayList!!)
        lv!!.setAdapter(customeAdapter)
    }

    interface ListItem {
         fun isHeader(): Boolean
         fun getName(): kotlin.String
    }

    private fun populateList() {

        var headerdone = 0
        var childdone = 0

        for (i in 0..19) {

            if (i == 0 || (i == 5) or (i == 10) or (i == 15)) {
                val vehicleModel = HeaderModel()
                vehicleModel.setheader(vehicleTypes[headerdone])
                listItemArrayList!!.add(vehicleModel)
                headerdone = headerdone + 1
            } else {
                val childModel = ChildModel()
                childModel.setChild(childnames[childdone])
                listItemArrayList!!.add(childModel)
                childdone = childdone + 1
            }
        }

    }

}
Read the below lines
interface ListItem {
         fun isHeader(): Boolean
         fun getName(): kotlin.String
    }

private var listItemArrayList: ArrayList<ListItem>? = null

    private val childnames = arrayOf(
        "Range Rover",
        "Lamborghini",
        "Rolls Royce",
        "Ferrari",
        "Harley davidson",
        "Ducati",
        "BMW",
        "Honda",
        "Boeing",
        "Airbus",
        "Royal Air",
        "Space X",
        "Horse",
        "Elephant",
        "Camel",
        "Donkey"
    )
There is an interface named ListItem with two functions : isHeader() and getName()

Then, there is an arrayList “listItemArrayList” which holds the objects of the interface “ListItem”
String array named “childnames” will hold the names of the vehicle companies which are the normal list view rows.

See the following:
 private val vehicleTypes = arrayOf("Cars", "Bikes", "Air Crafts", "Old Vehicles")
 Above line is string array “vehiceTypes” which holds the header names.

Now see the below code block:
private fun populateList() {

        var headerdone = 0
        var childdone = 0

        for (i in 0..19) {

            if (i == 0 || (i == 5) or (i == 10) or (i == 15)) {
                val vehicleModel = HeaderModel()
                vehicleModel.setheader(vehicleTypes[headerdone])
                listItemArrayList!!.add(vehicleModel)
                headerdone = headerdone + 1
            } else {
                val childModel = ChildModel()
                childModel.setChild(childnames[childdone])
                listItemArrayList!!.add(childModel)
                childdone = childdone + 1
            }
        }

    }

No comments:

Post a Comment