Sort listview with array adapter
Asked Answered
S

8

29

I have a listview connected to a custom array adapter. This list shows information received by a TCP connection which changes the dataSet...

I am able to sort the listview with sort (Comparator<? super T> comparator), but when the dataSet is changed, the listview is no more sorted...

I can use sort () every time the dataSet is changed, but I think this is not the best option...

How can I do that? Any suggestions?

EDIT

I am having problems in implementing the solutions presented...

MyComparatorB.java

public class MyComparatorB implements Comparator<DeviceB> {

private byte orderType;

public MyComparatorB(byte type) {

    this.orderType = type;

}

public int compare(DeviceB lhs, DeviceB rhs) {

    int res = 0;
    if (orderType == SortType.ALPHA) {
            res = (lhs.getName()).compareTo(rhs.getName());
        }
        else if (orderType == SortType.LAST_ACT) {
            res = (rhs.getTime().getTime()).compareTo(lhs.getTime().getTime());
        }
        return res;
    }

}

Snippet of my customArrayAdapter.java

    @Override
public void notifyDataSetChanged() {
    super.notifyDataSetChanged();
}


//-----------Order the content of the arrayAdapter------------//
public void sort(byte sortType) {

    super.sort(new MyComparatorB(sortType));
    notifyDataSetChanged();
}

In my MyActivity.java

myDevAdapter.sort(SortType.ALPHA);

When I am debugging, the method super.sort(new MyComparatorB(sortType)); is called and the constructor of MyComparatorB is called too. But the method compare(DeviceB lhs, DeviceB rhs) is never called and my arrayList is not sorted... What I am doing wrong?

Sparing answered 28/3, 2012 at 11:23 Comment(4)
why you don't use ArrayList and sort the array and restore array list!Ostrich
I think you should sort your array and call adapter.notifyDataSetChanged()Mcmillian
@Sparing : What is SortType here?Dustheap
@YuDroid: It is just a class where I define the possible types of sorting. Like: public class SortType{ public final static int ALPHA= 1; public final static int LAST_ACT= 2;}Sparing
A
48

I guess you need to override notifyDataSetChanged method in your adapter and perform sorting right before calling its super. See below:

@Override
public void notifyDataSetChanged() {
    //do your sorting here

    super.notifyDataSetChanged();
}

Doing so will sort the list whenever you call notifyDataSetChanged method to refresh list items. Otherwise, feed a sorted List/array to your adapter.


Or more preferably, use the sort method available in your adapter to get the job done.

adapter.sort(new Comparator<String>() {
    @Override
    public int compare(String lhs, String rhs) {
        return lhs.compareTo(rhs);   //or whatever your sorting algorithm
    }
});
Align answered 28/3, 2012 at 11:28 Comment(3)
the only way is call the super.sort(comparator) method every time the dataSet is changed?Sparing
yes, add this before calling super.notifyDataSetChanged, so that your data is sorted everytimeAlign
The .sort function automatically calls notifyDataSetChanged, so if you use this code with the built-in sort, you'll get into an infinite loop and overflow your stack. Only do this if you're managing the list yourself, but most people using an Array Adapter aren't doing that.Discriminator
O
4
  • Store data to an ArrayList
  • Attach Array to Adapter
  • Sort array and assign to itself
  • Use notifyDataSetChanged() to refresh Adapter
Ostrich answered 28/3, 2012 at 11:32 Comment(0)
N
4

This works for me

@Override
public void notifyDataSetChanged() {
    this.setNotifyOnChange(false);

    this.sort(new Comparator<String>() {
        @Override
        public int compare(String lhs, String rhs) {
            return lhs.compareTo(rhs);
        }
    });

    this.setNotifyOnChange(true);
}
Nabob answered 2/2, 2015 at 9:18 Comment(0)
D
1

Per elBradford's comment concerning the potential for a stack overflow resulting from the notifyDataSetChanged() approach, I ended up overriding the ArrayAdapter's add() method instead to ensure that the items maintain a sorted consistency when added one by one. (when calling addAll() I am sorting the items prior to; but I imagine you could override addAll() as well).

    @Override
    public void add(ListThing object) {
        super.add(object);
        this.sort(ListThing.sComparator);
    }
Damien answered 30/3, 2015 at 18:46 Comment(0)
T
0

Since is the Adapter filling the ListView, the only way is to pass the data object in a sorted way.

Toshiatoshiko answered 28/3, 2012 at 11:27 Comment(0)
E
0

Once the listView is sorted, call adapter.notifyDataSetChanged() from your activity.

Encase answered 28/3, 2012 at 11:31 Comment(0)
C
0

Based on waqaslam and KristianR's answer :

@Override
public void notifyDataSetChanged() {
    this.setNotifyOnChange(false);

    this.sort(new Comparator<String>() {

        @Override
        public int compare(String s1, String s2) {
            return s1.compareTo(s2);
        }
    });

    super.notifyDataSetChanged();
    this.setNotifyOnChange(true);
}

Hope it helps.

Constrictive answered 3/6, 2017 at 16:25 Comment(0)
M
0

Initialize ArrayAdapter and declare that we’re converting Strings into Views

val arrayAdapter = ArrayAdapter<String>(
            requireActivity(),
            R.layout.item_sample,
            R.id.tv_item_sample,
            samplesArray
)

Set the Adapter to the ListView, using setAdapter()

binding.lvSample.adapter = arrayAdapter

Perform sort and update the adapter.

arrayAdapter.sort { lhs, rhs -> lhs!!.compareTo(rhs!!) }
arrayAdapter.setNotifyOnChange(true)
Morisco answered 19/5, 2021 at 11:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.