1

Basically I have a spinner where you can sort your listview, the code i am using for sorting:

 if(arg2==0)
{
    Sorting_class.QueueSort(mList);
}
else if(arg2==1)
{
    Sorting_class.AlphaSort(mList);
}

After sorting and logging the list, it looks sorted without any problem! But as soon as I call adapter.notifydatasetchanged it messes up, for example it overrides the info of the last element with the first element. If my objects has a string name like this:

z
s
a

after calling alpha sort it looks like this from the logcat:

a
s
z

but after calling adapter.notifydatasetchanged to display the new info, it looks like this:

a
s
a

and it keeps on doing this after each sort until all elements get the same info. After sorting for the second time, my listview looks like this:

a
a
a

this is the code i am using for the sorting:

public static void QueueSort(ArrayList<item_base> mList)
    {
        Collections.sort(mList, new Comparator<item_base>() {

            @Override
            public int compare(item_base lhs, item_base rhs) {
                return lhs.GetTimeMil() < rhs.GetTimeMil() ? -1 : 1;
            }
        });
    }

    public static void AlphaSort(ArrayList<item_base> mList)
    {
        Collections.sort(mList, new Comparator<item_base>() {

            @Override
            public int compare(item_base lhs, item_base rhs) {
                return lhs.getmName().compareTo(rhs.getmName());
            }
        });
    }

this is the top part of the getview function " it's very long "

if(convertView == null)
                convertView = getActivity().getLayoutInflater().inflate(R.layout.listview_shopping, parent,false);

            final item_base item = mList.get(pos);
            Log.d("sorting" , "getview = " + item.getmName() + " pos = " + pos);

the only solution I found is to set the adapter again after each sort:

mAdapter = new Listview_customAdapter(getActivity(), mList, R.layout.listview_shopping);
                mListView.setAdapter(mAdapter);
hrskrs
  • 4,447
  • 5
  • 38
  • 52
  • 1
    @user3956566 , the problem is I want to keep it sorted/let the user picks the sort order how ever he likes at runtime , menaing I don't know what would the user's pick be , he might want to sort it according to price,names, or anything, I'm just kinda confused why it's not working in the first place! unless I set the adapter again! – user3504658 Feb 06 '15 at 14:46
  • @user3956566 , the problem is not about sorting , I handled it all , the problem is after sorting I need to update the listview so the user can see the new sorted list , if I use adapter.notifydatasetchanged it does something with the list and it replaces the content of the object to give me wrong result like the example that I provided , the second solution is to set the adapter everytime I sort , some say it's not a good idea , I i did override adapter.notifydatasetchanged and it turns out the list is sorted ok until I call the super method then it messes everything up. – user3504658 Feb 06 '15 at 15:51

2 Answers2

0

sort before you set the adapter

I mean after here:

if(arg2==0)
{
    Sorting_class.QueueSort(mList);
}
else if(arg2==1)
{
    Sorting_class.AlphaSort(mList);
}

//Set the adapter here (after sorting has occured)
mAdapter=new Listview_customAdapter(getActivity(),mList,R.layout.listview_shopping);
mListView.setAdapter(mAdapter);

According to your comment that this will affect the performance of the adapter:

If you are using recycle() view practice, that won't affect the perfromance that much.

So in getView() function: instead of:

View rootView = LayoutInflater.from(context)
  .inflate(R.layout.banana_phone, parent, false);

if you use:

if (convertView == null) {
    convertView = LayoutInflater.from(context)
      .inflate(R.layout.banana_phone, parent, false);
}

ListView recycles the views that are not shown any more, and gives them back through convertView

For further details you can read here

hrskrs
  • 4,447
  • 5
  • 38
  • 52
  • I want the user to sort this anytime he wants/ or even keep it sorted at all times even after editing it , this solution would work if I want to sort it one time that is before returning the view, also I can apply your solution every time I sort the list but it's not a good idea , my problem is why it's causing problems in the first place ? – user3504658 Feb 06 '15 at 14:43
  • this solution will work for sure except if your case is anykind of special case. For further details you have to extend your post by showing a little more code maybe – hrskrs Feb 06 '15 at 15:07
  • Sorry if you couldn't understand my English It's not my native language , anyways , your solution works , I can replace adapter.notifydatasetchanged with your code , which basically means setting the adapter every time I sort the list , the problem with this is it might not be as fast , and it's not a good idea , specially in my case , i'm overriding adapter.notifydatasetchanged so I can update the list and keep it sorted , so I need to set the adapter everytime I sort! which is not good. – user3504658 Feb 06 '15 at 15:35
  • You have misunderstood the concept of `Adapter`. I have `updated` the `answer` with further explanation. Also dont forget that if an answers works well/ solves your problem you should `vote` that as `right answer` – hrskrs Feb 06 '15 at 15:56
  • thanks for your help , I actually read it in this site that it'll not be as fast , I'm still trying to figure out why it isn't working when I use adapter.notifydatasetchanged in the first place, thanks again. – user3504658 Feb 06 '15 at 16:17
0

You need to create two ArrayLists.

So when you use the sort algorithm you are creating a second ArrayList and not overwriting the original ArrayList.

ArrayList list1 and ArrayList list2.

copy the values of list1 into list2.

Then perform any sorting on list2.

Depending on whether the user selects the sorted list or the original list, set your adapter with the selected list. This means you alter the list in your adapter and then set it each time a different sort is selected.

If you are concerned about setting the adapter each time. You can see another way to sort the items of your adapter bypassing this in this code, which comes from this answer here. I am not sure if this a more cost effective way to achieve what you are wanting to achieve. That choice is ultimately yours.

Community
  • 1
  • 1
  • Thanks for your answer , but I think it would be much slower if I used your solution " if I understood you correctly " the problem is not in returning in the original list , the problem is after updating or to be specific calling " adapter.notifydatasetchanged " it messes up the list such that the first element would override the last element like the example that I gave , and it keeps on doing this , it's not a matter of sorting, thanks again , I think I'll just set the adapter every time I sort until I figure this out. – user3504658 Feb 06 '15 at 16:19