Kotlin Android – GridView – Sort Ascending and Descending

 

In many cases you normally need your data sorted. In this class we see how to sort data in both ascending and descending manner using Kotlin Programming language.

What is Kotlin?

Kotlin is a programming language targeting the Java
platform. Kotlin is concise, safe, pragmatic, and focused on interoperability with Java code.

Kotlin is usble almost everywhere Java is used today – for server-side development, Android apps, and much more.

Kotlin like Java is a statically typed programming language. This implies the type of every expression in a program is known at compile time, and the compiler can validate
that the methods and fields you’re trying to access exist on the objects you’re using.

We are Building a Vibrant YouTube Community

We have a fast rising YouTube Channel of friends. So far we’ve accumulated more than 2.6 million agreggate views and more than 10,000 subscribers. Here’s the Channel: ProgrammingWizards TV.

Please go ahead subscribe(free obviously) as well. If you have a question or a comment you can post there instead of in this site.People are suggesting us tutorials to do there so you can too.

Here’s this tutorial in Video Format.

Defining Packages in Kotlin

Normally classes are organized in packages in Java. This applies to Kotlin as well.

Package specification should be at the top of the source file:

package info.camposha
import java.util.*
class Starter{
    ...
}

However, be aware that it’s not required to match directories and packages: source files can be placed arbitrarily in the file system.

Defining Functions in Kotlin

Roughly speaking, functions in Kotlin are the equivalent of methods in java.

Functions can take input parameters and can return values. Here’s such a function:

fun sum(a: Int, b: Int): Int {
    return a + b
}

This can be condensed into a single line given that it has an expression body and we can infer the retur types:

fun sum(a: Int, b: Int) = a + b

However, if functions do not return any meaningful value:

fun printSum(a: Int, b: Int): Unit {
    println("sum of $a and $b is ${a + b}")
}

Classes in Kotlin

You create a class in Kotlin using the class keyword:

class MyClass {..}

Classes can inherit from other classes.

class MyClass : android.app.Activity {..}

So in the above cases you’ve turned an ordinary class into an Activity just through inheritance.

Class Properties in Kotlin – Fields

Normally classes are templates for objects. They define an entity.

And entities certainly can have properties, so classes can also have properties.

class Spaceship {
    var name: String = ...
    var topSpeed: String = ...
    var lifeSpan: String = ...
    var propellant: String? = ...
    var destination: String = ...
}

Then we can use them, accessing the fields directly:

fun getSpaceship(s: Spaceship): Spaceship {
    val result = Spaceship() // there's no 'new' keyword in Kotlin
    result.name = s.name // accessors are called
    result.propellant = s.propellant
    // ...
    return result
}

Class Properties in Kotlin – Getters and Setters

The full syntax for declaring a property is:

var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

We can write custom accessors, very much like ordinary functions, right inside a property declaration. Here’s an example of a custom getter and setter:

var mrString: String
    get() = this.toString()
    set(value) {
        setDataFromString(value) // parses the string and assigns values to other properties
    }

By convention, the name of the setter parameter is value, but you can choose a different name if you prefer.

Class Properties in Kotlin – Late-Initialized Properties and Variables

If you declare a property that is having a non-null type, you have to initialize it in the constructor.

However, if your design doesn’t go with that then you can mark the property with the lateinit modifier:

public class MrTest {
    lateinit var subject: TestSubject

    @SetUp fun setup() {
        subject = TestSubject()
    }

    @Test fun test() {
        subject.method()  
    }
}

The type of the property or variable must be non-null, and it must not be a primitive type.

Let’s Create the App

(a). build.gradle(app level)

Inside our app level build.gradle first you want to make sure that Kotlin plugin has been added as a dependency.

Also that it has been applied. Check below.

Normally if your are using android studio, just mark include kotlin in the Create Project and these will be done for you by the IDE.

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "info.camposha.kotlinsortgridview"
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

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

}

(b). activity_main.xml

This layout will get inflated to our Main Activity layout.

It’s an XML file. XML normally stands for eXtensible Markup Language and is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable.

Android user interfaces are normally written in XML format. This makes them agnostic to the logic code written in Kotlin.

The encoding formats used with XML documents are either utf-8 or utf-16, normally and in this case we use the former.

We have a RelativeLayout element as the root element. This layout normally arranges its children relative to other each other.

The first of those children is the extView, a View that is meant to render static Text. In this case we use it show the header label of our Kotlin Android application.

Then we will have another sibling element called GridView. This is a widget which is an adapterview. It’s similar to other adapterviews like ListView and Spinner in that they render lists of data and need an adapter to bind that data.

However GridViews normally render data in a two-dimensional format, that is rows and columns.

Lastly we have a button that is meant to toggle sort between ascending and descending.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="info.camposha.kotlinsortgridview.MainActivity">

    <TextView
        android:id="@+id/headerLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:fontFamily="casual"
        android:text="Array Sorting GridView"
        android:textAllCaps="true"
        android:textSize="24sp"
        android:textStyle="bold" />

    <Button
        android:id="@+id/mySortBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="12dp"
        android:fontFamily="serif-monospace"
        android:text="Toggle Sort" />

    <GridView
        android:id="@+id/myGridView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/mySortBtn"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_below="@+id/headerLabel"
        android:numColumns="3"
        android:layout_marginTop="33dp" />

</RelativeLayout>

Let’s now move to our MainActivity class.

(c). MainActivity.kt

1. What is an Activity in Kotlin Android?

Generally an activity is a single, focused thing that the user can do. Users normally act when they are interacting with your application.

This act may be sending an email or playing some music, or clicking a button. In Kotlin Android, or Android as a whole, they act on Activities.

An Activity is an android component so is fundamental to how android works. Activities have life cycle methods representing various stages in its life cycle.

Activities get created by deriving from android.app.Activity as we do here in Kotlin:

class MainActivity : Activity() {..}

Of course we’ve already imported some packages:

import android.app.Activity
import android.os.Bundle
import android.widget.*
import java.util.*

2. Create Instance Properties

These include properties of type GridView and Button, which are our user interface widgets.

    private lateinit var gv: GridView
    private lateinit var mySortButton: Button

The GridView will be used to contain the data that need to sorted.

These two are not null and yet we don’t want to initialize them in the constructor, the way any non-null property has to. So we mark them as lateinit.

Then we create a property to act as our data source. We use the arrayOf() function to create an array of galaxies data:

    private var galaxies = arrayOf("Sombrero", "Cartwheel", "Pinwheel", "StarBust", "Whirlpool", "Ring Nebular", "Own Nebular", "Centaurus A", "Virgo Stellar Stream", "Canis Majos Overdensity", "Mayall's Object", "Leo", "Small Magellonic Cloud", "Large Magellonic Cloud", "Milky Way", "Whirlpool", "Black Eye Galaxy", "IC 1011", "Messier 81", "Andromeda", "Messier 87")

Then we turn that Array into a List using the asList() method of the java.util.Arrays class:

    var galaxiesList = Arrays.asList(*galaxies)

And finally two helper properties to help us maintain state of sorting, whether data is unsorted or sorted in ascending or sorted in descending manner.

    private var sortAscending = true
    private var unSorted = true

3. Sort Data in Ascending or Descending Manner via Collections

Then we come to how we will actually sort our data.

Fortunately we have the Collections class which will allow us do that easily.

But what is this Collections class?

Please don’t confuse it with Collection<E> which is the root interface of the Collection hierarchy.

Collections on the other hand is a class that consists exclusively of static methods that operate on or return collections.

It derives from the Object class:

java.lang.Object
   ↳    java.util.Collections

Among those static methods we are interested in the sort() and reverse().

sort() will sort data in ascending manner. Then reverse() can reverse the already sorted data in descending manner.

        if (sortAscending)
            Collections.sort(galaxiesList)
        else
            Collections.reverse(galaxiesList)

        sortAscending = !sortAscending

You can see we reverse the state after sorting.Note that we have one button that will sort our data in descending manner the first time it’s clicked.

Then when clicked again it simply reverses it and then updates or negates the state of sortAscending variable.

So we will subsequently be toggling between the ascending and descending sort orders.

4. Bind Data to GridView Kotlin Android

Yeah we bind data to GridView using ArrayAdapter:

        gv.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, galaxiesList)
        gv.onItemClickListener = AdapterView.OnItemClickListener { adapterView, view, i, l -> Toast.makeText(this@MainActivity, galaxiesList[i], Toast.LENGTH_SHORT).show() }

We listen to onClick events and show a Toast message with the clicked ite,.

Well here’s the full Kotlin source code.

Full Code

Our Kotlin MainActivity class.

package info.camposha.kotlinsortgridview

import android.app.Activity
import android.os.Bundle
import android.widget.*
import java.util.*

class MainActivity : Activity() {

    private lateinit var gv: GridView
    private lateinit var mySortButton: Button
    private var galaxies = arrayOf("Sombrero", "Cartwheel", "Pinwheel", "StarBust", "Whirlpool", "Ring Nebular", "Own Nebular", "Centaurus A", "Virgo Stellar Stream", "Canis Majos Overdensity", "Mayall's Object", "Leo", "Small Magellonic Cloud", "Large Magellonic Cloud", "Milky Way", "Whirlpool", "Black Eye Galaxy", "IC 1011", "Messier 81", "Andromeda", "Messier 87")

    var galaxiesList = Arrays.asList(*galaxies)

    private var sortAscending = true
    private var unSorted = true
    /*
    SORT
     */
    private fun sortData() {

        if (sortAscending)
            Collections.sort(galaxiesList)
        else
            Collections.reverse(galaxiesList)

        sortAscending = !sortAscending
        gv.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, galaxiesList)
        gv.onItemClickListener = AdapterView.OnItemClickListener { adapterView, view, i, l -> Toast.makeText(this@MainActivity, galaxiesList[i], Toast.LENGTH_SHORT).show() }
    }
    /*
    INITIALIZE GRIDVIEW
     */
    private fun initializeGridView() {
        gv = findViewById(R.id.myGridView)
        gv.adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, galaxies)

        mySortButton = findViewById(R.id.mySortBtn)
        mySortButton.setOnClickListener { sortData() }
    }

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

        initializeGridView()
    }
}

(d). Results

I used Nox Player Emulator.

First unsorted data in our gridview. This before the user clicks the Toggle Sort button:

Kotlin Android Sort GridView

Kotlin Android Sort GridView

Then sorted data in ascending manner. This after he’s clicked the Toggle Sort button:

Kotlin Android Sort GridView

Kotlin Android Sort GridView

And lastly data sorted in descending manner. The data was first sorted in ascending manner. He clicks Toggle Sort and we toggle the sort to descending order:

Kotlin Android Sort GridView

Kotlin Android Sort GridView

Best Regards.

Share



Share an Example

Share an Example

Browse
What is the capital of Egypt? ( Cairo )