Android Programming

Android Arrays - Sort Descending and Ascending Order

We all know Java provides us the java.util.Collection framework for manipulating data including sorting.

With this we can sort any collection. However, an array is a built language feature and is not found in java.util.Collection.

However we have the Array class which provides us with the asList method that we can use tonvert our Array into a List then sort it via the Collections API.

List<String> myList = Array.asList(myStringArray);

We can then call the Collections.sort() passing in our List. This sorts the data in ascending order by default.

Collections.sort(galaxiesList);

We can then reverse it into descending, which is the opposite of ascending:

Collections.reverse(galaxiesList)

Sort ListView Array Ascending and Descending

Sort ListView Array Ascending and Descending

Sort ListView Array Ascending and Descending

Create Project

  1. First create an empty project in android studio. Go to File --> New Project.

  2. Type the application name and choose the company name. New Project Dialog

  3. Choose minimum SDK. Choose minimum SDK
  4. Choose Empty activity. Choose Empty Activity
  5. Click Finish. Finish

This will generate for us a project with the following:

  • 1 Activity - MainActivity.java
  • 1 Layout - activity_main.xml.

The activity will automatically be registered in the android_manifest.xml. Android Activities are components and normally need to be registered as an application component. If you've created yours manually then register it inside the <application>...<application> as following, replacing the MainActivity with your activity name:

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

You can see that one action and category are specified as intent filters. The category makes our MainActivity as launcher activity. Launcher activities get executed first when th android app is run.

Project Structure

Here's our project structure. Project Structure

Layouts

We'll have only one layout, our activity_main.xml. We are working with:

  • ListView
  • Button
  • TextView
  • RelativeLayout

Here's the component tree: Component Tree

Here's our design pallete: Design pallete

Here's our XML Layout:

<?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.tutorialsloop.hp.arraysortcollection.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 ListView"
        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" />

    <ListView
        android:id="@+id/myListView"
        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:layout_marginTop="33dp" />

</RelativeLayout>

Java Code

We'll have only one class the MainActivity.

First we specify the package name:

package info.tutorialsloop.hp.arraysortcollection;

Then create the class

public class MainActivity{}

Let's add the imports we'll use:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

We then make the class derive from Activity.

public class MainActivity extends Activity {}

Our class will have the following instance fields. Instance fields are private properties of a class.

    private ListView myListView;
    private Button mySortButton;
    private String[] galaxies={"Sombrero", "Cartwheel", "Pinwheel", "StarBust","Whirlpool","Ring Nebular", "Own Nebular","Centaurus A", "Virgo Stellar Stream", "Canis Majos Overdensity"
            , "Mayall's Object", "Leo", "Milky Way","IC 1011","Messier 81", "Andromeda", "Messier 87"};
    private boolean sortAscending=true;
    private boolean unSorted=true;
  • The ListView is our adapterview onto which we'll bind data.
  • The button will toggle between ascending and descending order.
  • The galaxies is a String array that will act as our data source.
  • Then sortAscending is also a boolean that will maintain for us the state of sorting whether ascending or descending.
  • The unsorted will help us determine the first time the user has clicked the sort button so that we can sort only once then subsequently only reverse instead of resorting every time the user clicks the sort button.

Let's continue.

We'll the create an initializeViews() method to initialize our views.

    private void initializeViews()
    {
        myListView=findViewById(R.id.myListView);
       //with arrayadapter you have to pass a textview as a resource, and that is simple_list_item_1
        myListView.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1,galaxies));

        mySortButton=findViewById(R.id.mySortBtn);
        mySortButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sortData();
            }
        });
    }

In the above we reference the ListView from our XML layout using the findViewById(). This method is defined in the android.app.Activity class from which our MainActivity derives. We then call the ListView's setAdapter() method. And pass it an instance of an ArrayAdapter. Our ArrayAdapter takes the following parameters:

  • Context object.
  • TextView resource
  • Data Source

We also reference the button from the XML layout. And invoke it's setOnClickListener event handler. Then call sortData() inside it. We'll define this method next.

Then sortData() method:

This method will be responsible for sorting our data in both ascending and descending.

private void sortData()
    {
        List<String> galaxiesList=Arrays.asList(galaxies);

        if(unSorted)Collections.sort(galaxiesList);
        else Collections.reverse(galaxiesList);

        sortAscending=!sortAscending;
        unSorted=false;

        myListView.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1,galaxiesList));
    }

First we convert our Array to an ArrayList using the asList() method, passing in the array as a parameter. This gives us a List object which is passable to a collection to be sorted.

We check if our unSorted boolean is set to true. If so then we sort the data using the Collection's sort() method, passing in our List object.

If it's false then we simply reverse the Collection using the reverse() method.

We then toggle sortAscending to its negation, then update the unSorted to false.

After that we set our adapter to our ListView. This time however we pass our sorted List object as the data source.

Let's now come to the last part of our MainActivity class.

The OnCreate() method.

This method is one of lifecycle methods for android. This means it get's called at a particular time in the lifetime of an activity. In this case after the creation.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initializeViews();
    }

It's a method we are overriding. This means it has already been defined in the parent class. The parent class of our MainActivity is android.app.Activity.

The first requirement when overriding a lifecycle method is to invoke the onCreate() method that's defined inside that parent class. So we call super.onCreate().

And we pass it a Bundle object. A Bundle is a class that allows us map string values to parceable types. It's a class belonging to android.so package and deriving from android.os.BaseBundle.

After that we call the setContentView() passing in our layout. This method belongs to our Activity. it knows and will inflate our XML layout into an android.view.View object that will be used as the user interface we interact with.

Finally we invoke the initialize() method.

And that's it. Here's the complete source:

package info.tutorialsloop.hp.arraysortcollection;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MainActivity extends Activity {

    private ListView myListView;
    private Button mySortButton;
    private String[] galaxies={"Sombrero", "Cartwheel", "Pinwheel", "StarBust","Whirlpool","Ring Nebular", "Own Nebular","Centaurus A", "Virgo Stellar Stream", "Canis Majos Overdensity"
            , "Mayall's Object", "Leo", "Milky Way","IC 1011","Messier 81", "Andromeda", "Messier 87"};
    private boolean sortAscending=true;
    private boolean unSorted=true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initializeViews();
    }

    private void initializeViews()
    {
        myListView=findViewById(R.id.myListView);
       //with arrayadapter you have to pass a textview as a resource, and that is simple_list_item_1
        myListView.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1,galaxies));

        mySortButton=findViewById(R.id.mySortBtn);
        mySortButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sortData();
            }
        });
    }
    private void sortData()
    {
        List<String> galaxiesList=Arrays.asList(galaxies);

        if(unSorted)Collections.sort(galaxiesList);
        else Collections.reverse(galaxiesList);

        sortAscending=!sortAscending;
        unSorted=false;

        myListView.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1,galaxiesList));
    }
}