0

I have an adapter that has a date in the row. When the user updates the date, I want the rows to re-sort based on my UNIX time in the object date property. I believe I need to use a Comparator and / or a Collections sort for this on my ArrayList<Object>. As seen from this question.

My question is this: When I call notifyDataSetChanged(), where in the ArrayAdapter does the sorting need to take place? Or would it be outside of the adapter when I build it (which would not make sense to me)?

Community
  • 1
  • 1
TheLettuceMaster
  • 15,594
  • 48
  • 153
  • 259
  • Depends on your adapter and loader implementation. Could be in `loadOnBackground()`, in your `ContentProvider`, in your `ArrayList`, .... – Trinimon Mar 08 '15 at 22:06
  • @T My `ContentProvider` is my `ArrayAdapter`. I am using a `ListView` still. Let me know if I need ot add more details. – TheLettuceMaster Mar 08 '15 at 22:13
  • If you have a reference to your adapter's data, just do a sort on that before calling the notify. You mention that this doesn't make sense but when your adapter is constructed, it just points to this data, they are the same object. – tachyonflux Mar 08 '15 at 22:39
  • It is highly inefficient to do a full sort when you only have one item out of place btw. – tachyonflux Mar 08 '15 at 22:41
  • So in the Constructor of the `ArrayAdapter` I can do the Collection/Comparator sort? – TheLettuceMaster Mar 08 '15 at 22:41
  • Um... you're changing the data after the adapter is constructed, right? How would sorting it in the constructer solve your problem? – tachyonflux Mar 08 '15 at 22:46
  • @karaokyo Sorry, dumb question -- I just looked at your comment closer. So just do it before i call `notify`. Normally when I call `notify` I am just changing one price of data, at that one position so I didn't think about how I can change the entire adapter at that same point. – TheLettuceMaster Mar 08 '15 at 22:48
  • Ok, so you got it or do you still have an issue? – tachyonflux Mar 08 '15 at 22:50
  • I got it. Feel free to add an answer and I will mark it. – TheLettuceMaster Mar 08 '15 at 22:55
  • I don't think it will have a very wide audience, but OK :P – tachyonflux Mar 09 '15 at 02:14

2 Answers2

1

Do the sort on your adapter's backing data object before calling notifyDataSetChanged.

tachyonflux
  • 20,103
  • 7
  • 48
  • 67
  • Thanks. I guess I just need to recreate the adapter every time I call 'notify'. Just curious, why do you say it is inefficient? Its just about 75 list items stored in a SQLite DB. I think that should be fine. – TheLettuceMaster Mar 09 '15 at 02:22
  • You will not have to recreate the adapter every time, but only sort the internal referenced array/collection. In case were using a custom Adapter referencing your data structure, you can do an approach having a self sorteable one, like a TreeSet (or better a SortedList like this one: http://blog.scottlogic.com/2010/12/22/sorted_lists_in_java.html ) - Remember that the TreeSet implementation works having the Comparator/able consistent with equals. – DNax Mar 09 '15 at 02:32
  • I was just saying that since you're dealing with an almost sorted list, you can write an algorithm that takes O(n) rather than `Collections.sort`'s O(n log n) – tachyonflux Mar 09 '15 at 02:59
0

For an answer with code, place this either in your adapter or wherever you need to do your sorting:

            adapter.sort(new Comparator<Ledger>() {
                public int compare(MyObject lhs, MyObject rhs) {
                    return  rhs.transaction_date.compareTo(lhs.transaction_date);
                }
            });
            notifyDataSetChanged();

This is the code I used to get this working. Note: I wanted to sort in descending order so I returned rhs before lhs. Also, this maintains your ListView position which is always good.

TheLettuceMaster
  • 15,594
  • 48
  • 153
  • 259