Reputation: 12352
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?
Upvotes: 29
Views: 69125
Reputation: 255
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)
Upvotes: 0
Reputation: 81
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.
Upvotes: 0
Reputation: 556
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);
}
Upvotes: 1
Reputation: 68177
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
}
});
Upvotes: 48
Reputation: 430
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);
}
Upvotes: 4
Reputation: 2278
Upvotes: 4
Reputation: 7634
Once the listView is sorted, call adapter.notifyDataSetChanged() from your activity.
Upvotes: 0
Reputation: 157437
Since is the Adapter filling the ListView, the only way is to pass the data object in a sorted way.
Upvotes: 0