Kotlin Android - RecyclerView Sort Ascending/Descending


This is an android tutorial of how to sort in both ascending and descending manner in recyclerview using Kotlin programming language.

You click a button to toggle between ascending and descending manner.

But first let's introduce some terms.

Data Sorting

Generally data sorting refers to the process of arranging data in a particular manner for several uses. These uses include ease of analysis and efficiency. Sorted data are easier to read and analyze which is good for us humans. However they are also good for computers as it makes processing of data much more efficient. The main reason for these is that we or the computers can ignore some data and jump to specific location.

It's why for example binary search is much faster and efficient than many other searches including linear searching. This is because that algorithm involves splitting data into two and ignoring one half. On the other hand with linear search the data is normally not sorted hence you have to search against all items.

Imagine if in your contacts application in your mobile device, if the contacts were not sorted. If you wanted to find a given contact, yet the contact was listed the last in the list, you would have to scroll through all contacts. You would be checking the contacts one by one. However for sorted data that is easy as you simply scroll to the appropriate letter. For example, if the contact's name is Zak, then you would certainly scroll to the last item directly.

RecyclerView

RecyclerView is a list component that allows us render large data sets efficiently. These days it is the most commonly used adapterview. This courtesy of it's felxibility, power and ease of use. Like other adapterviews, recyclerviews need adapter. It is the adapter that maintains the data source on behalf of recyclerview.

Given the large use scenarios of recyclerviews, it makes sense to be able to sort them.

Our Video tutorial

Have a look at our video tutorial here:

Let's look at Code

1. Gradle Scripts

(a). build.gradle(app)

This is our app level build.gradle.

Our programming language is Kotlin hence we will apply the kotlin-android plugin, alongside the com.android.application plugin.

We will also add the design support as well as the cardview under the dependencies DSL.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    testImplementation 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:28.0.0-beta01'
    implementation 'com.android.support:design:28.0.0-alpha3'
    implementation 'com.android.support:cardview-v7:28.0.0-alpha3'

}

We've added the appcompat, cardview and design support libraries. Recyclerview is contained in the design support.

2. Layouts

(a). activity_main.xml

We have a button on top of a recyclerview. The recyclerview will display our data.

When the button is clicked, we toggle the sort between ascending and descending manner.

We wrap these two widgets in a relativelayout.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">
     <Button
        android:text="Toggle Sort"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorAccent"
        android:padding="5dp"
        android:id="@+id/sortBtn"
        android:layout_marginRight="5.0dp" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_marginTop="40dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>

You can see you declare recyclerview using the android.support.v7.widget.RecyclerView class. Then we've assigned it an id which will be used to identify it.

(b). model.xml

At the root view of this layout we have a cardview.

Our CardView will have only a simple textview.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_margin="10dp"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="5dp"
    android:layout_height="200dp">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text="Name"
                android:id="@+id/nameTxt"
                android:padding="10dp"
                android:textColor="@color/colorAccent"
                android:textStyle="bold"
                android:layout_alignParentLeft="true"
                />

</android.support.v7.widget.CardView>

3. Kotlin Code

(a). MainActivity.kt

Then we have our MainActivity. The class obviously derives from appcompatactivity.

package com.devosha.kotlin_recyclerview_sort

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.widget.Button
import java.util.*

class MainActivity : AppCompatActivity() {

    internal lateinit var rv: RecyclerView
    internal lateinit var sortBtn: Button
    internal lateinit var adapter: MyAdapter
    private var ascending = true
    companion object {
        private val spacecrafts = ArrayList<String>()
    }

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

        this.initializeViews()
        this.fillSpacecrafts()
    }

    private fun initializeViews() {
        rv = findViewById(R.id.rv)
        rv.setLayoutManager(LinearLayoutManager(this))
        sortBtn = findViewById(R.id.sortBtn)
        sortBtn.setOnClickListener {
            sortData(ascending)
            ascending = !ascending
        }
    }

    private fun sortData(asc: Boolean) {
        //SORT ARRAY ASCENDING AND DESCENDING
        if (asc) {
            spacecrafts.sort()
        } else {
            spacecrafts.reverse()
        }
        adapter = MyAdapter(this, spacecrafts)
        rv.adapter = adapter
    }

    private fun fillSpacecrafts() {

        spacecrafts.clear()
        spacecrafts.add("Kepler")
        spacecrafts.add("Casini")
        spacecrafts.add("Voyager")
        spacecrafts.add("New Horizon")
        spacecrafts.add("James Web")
        spacecrafts.add("Apollo 15")
        spacecrafts.add("WMAP")
        spacecrafts.add("Enterprise")
        spacecrafts.add("Spitzer")
        spacecrafts.add("Galileo")
        spacecrafts.add("Challenger")
        spacecrafts.add("Atlantis")
        spacecrafts.add("Apollo 19")
        spacecrafts.add("Huygens")
        spacecrafts.add("Hubble")
        spacecrafts.add("Juno")
        spacecrafts.add("Aries")
        spacecrafts.add("Columbia")

        //ADAPTER
        adapter = MyAdapter(this, spacecrafts)
        rv.setAdapter(adapter)
    }

}

//end

We've started by declaring several variables as instance fields. The y include:

  1. Button - Will be clicked so as to sort.
  2. RecyclerView - Will render our data.
  3. Adapter - Our recyclerview adapter.
  4. Boolean - Will allow us to maintain the status of the sort. For example true means the data is the sorted in ascending while false means the data is either unsorted or sorted in descendng manner.
(b). MyAdapter.kt

Here's our adapter class.

Because we use a recyclerview, our adapter is RecyclerView.Adapter with VH being our ViewHolder class.

package com.devosha.kotlin_recyclerview_sort

import android.content.Context
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

import java.util.ArrayList

import android.view.View.inflate
import android.widget.TextView

/**
 * class MyAdapter.
 * This class is our MyAdapter class.
 * It will ReyclerView.Adapter class. Via the constructor we will pass a Context,
 * and an ArrayList of spacecrafts.
 */
class MyAdapter(internal var c: Context, internal var spacecrafts: ArrayList<String>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
    /*
    class: MyViewHolder
    This is our View Holder class.
   */
    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        internal var nameTxt: TextView = itemView.findViewById(R.id.nameTxt)
    }

    override fun getItemCount(): Int {
        return spacecrafts.size
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val v = LayoutInflater.from(c).inflate(R.layout.model, parent, false)
        return MyViewHolder(v)
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        //BIND DATA
        holder.nameTxt.text = spacecrafts[position]
    }
}
//end

Download

You can download full source code below.

No. Location Link
1. GitHub Direct Download
2. GitHub Browse

How do You Feel after reading this?

According to scientists, we humans have 8 primary innate emotions: joy, acceptance, fear, surprise, sadness, disgust, anger, and anticipation. Feel free to tell us how you feel about this article using these emotes or via the comment section. This feedback helps us gauge our progress.

Help me Grow.

I set myself some growth ambitions I desire to achieve by this year's end regarding this website and my youtube channel. Am halfway. Help me reach them by:




Recommendations


What do You Think


Previous Post Next Post