0

I am using a custom adapter to populate a ListView. Data are retrieved with a Query i make to a distant DB.

I do an iteration inside the custom adapter of the query's results and then, each object is sent to the the listview using notifyDataSetChanged()

The objects contain a value String TimeUpdated (DateTime class).

I would like to sort the object descending in my listview depending of the TimeUpdated value.

From what i have read, i have to do this inside my iteration before calling 'notifyDataSetChanged();' inside my adapter.

But i don't know how to do this.

If my understanding is right, could someone share sample code to do this ?

Regards to the community


UPDATE : 08/10/2015

I think i have to create an arrayList in my adapter from the iteration of my query's results.

So i did this : 1.I iterate the results of my query and place each object in a arrayList. So i have an arraylist containing Objects. 2.Each objects has got a String value containing "Latitude, Longitude".

I want to sort them from their distance from me.

Calculation of distance works already.

I can't figure out a way to sort the list now ?

private void sortMyList(List<Document> resultsArray) {
    Collections.sort(resultsArray, new Comparator<Document>() {
        @Override
        public int compare(Document doc1, Document doc2) {
            String DistanceDoc1 = Double.toString(calculateDistance(location.getLongitude(),location.getLatitude(), getDocLng(doc1), getDocLat(doc1)));
            String DistanceDoc2 = Double.toString(calculateDistance(location.getLongitude(),location.getLatitude(), getDocLng(doc2), getDocLat(doc2)));
            return DistanceDoc1.compareToIgnoreCase(DistanceDoc2);
        }
    });
    notifyDataSetChanged();
}

Important :

I use two adapter to construct the ListView with the results of my Query. A parent called LiveQueryAdapter, that extends from BaseAdapter. And the one inside a Fragment called DocumentAdapter...with extends from LiveQueryAdapter

LiveQueryAdapter Class

public class LiveQueryAdapter extends BaseAdapter {

public String TAG = "LiveQueryAdapter";
private LiveQuery query;
private QueryEnumerator enumerator;
private Context context;

int i;

public LiveQueryAdapter(Context context, LiveQuery query) {
    this.context = context;
    this.query = query;

    query.addChangeListener(new LiveQuery.ChangeListener() {
        @Override
        public void changed(final LiveQuery.ChangeEvent event) {

            ((Activity) LiveQueryAdapter.this.context).runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    enumerator = event.getRows();

                     ***I am thinking about iterate and sort  objects         here...***

                    notifyDataSetChanged();
                }
            });
        }
    });

    query.start();
}

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

    super.notifyDataSetChanged();
}

@Override
public int getCount() {
    return enumerator != null ? enumerator.getCount() : 0;
}

@Override
public Object getItem(int i) {
    return enumerator != null ? enumerator.getRow(i).getDocument() : null;
}

@Override
public long getItemId(int i) {
    return enumerator.getRow(i).getSequenceNumber();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return null;
}

public void invalidate() {
    if (query != null)
        query.stop();
}

}

DocumentAdapter Class (inside class of my Fragment)

    private class DocumentAdapter extends LiveQueryAdapter {

    public DocumentAdapter(Context context, LiveQuery matchQuery) {
        super(context, matchQuery);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) parent.getContext().
                    getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.custom_item_matches_fragment, null);
        }

        final Document doc = (Document) getItem(position);

        Log.i(TAG, "doc is : " + doc.getProperty("userId"));

        if (doc == null || doc.getCurrentRevision() == null) {
            return convertView;
        }

     HERE I DO SET VIEWS IN MY LAYOUT (TEXT & PICTURES)

        return convertView;

    }
}

In my Fragment :

This adapter is called in onCreateView() of my Fragment like this :

    mAdapter = new DocumentAdapter(getActivity(), matchQuery);

    // Set the adapter
    mListView = (ListView) view.findViewById(R.id.listview_matches);
    mListView.setAdapter(mAdapter);
    // Set OnItemClickListener so we can be notified on item clicks
    mListView.setOnItemClickListener(this);
Heretyk
  • 173
  • 1
  • 1
  • 8
  • 2
    why not do the sorting as part of the DB query? – petey Oct 07 '15 at 15:17
  • I cannot as i am already filtering with some keys, i cannot make add another sorting. – Heretyk Oct 07 '15 at 15:31
  • 1
    that makes sense... can you edit your question and add your current adapter code? and also the class that _"contain a value String TimeUpdated"_? – petey Oct 07 '15 at 15:47
  • I will post relevant part of adapter ok. For the class, it is not useful. Just imagine a query that returns 10 Object X. Each Object is a JSONObject that contain a variable String "lastTimeUpdated". I want to sort the results descending comparing "lastTimeUpdated". – Heretyk Oct 07 '15 at 17:29
  • @petey : As requested, i posted adapter codes. For your Information 'Document' object are the objects that i want to sort :) – Heretyk Oct 07 '15 at 17:44
  • can you also add the document class? – petey Oct 07 '15 at 18:04

1 Answers1

0

Perhaps this could help

   class myAdapter extends BaseAdapter {

        private List<String> mList;

        public void setList(List<String> list){
            mList.clear();
            mList.addAll(list);
            sortMyList();
        }

        private void sortMyList() {
            //Do sorting of the list

            notifyDataSetChanged();
        }

        @Override
        public int getCount() {
            return 0;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return null;
        }
    }

You could then call

myAdapter.setList(list);

which will set the list and sort it.

Sorting:

Collections.sort(empList, new Comparator<Employee>(){
  public int compare(Employee emp1, Employee emp2) {
    return emp1.getFirstName().compareToIgnoreCase(emp2.getFirstName());
  }
});

taken from here: Android-java- How to sort a list of objects by a certain value within the object

Community
  • 1
  • 1
  • Thanks . In my case, the list will be a list of Objects ( not string) . how to sort Object inside 'sortMyList()' depending of the value of one of it's variable ? (an int, a string, a Date etc...) – Heretyk Oct 07 '15 at 15:35
  • Can i use this even if the value i compare are not Parameters of the Object ? String DistanceDoc1 = Double.toString(calculateDistance(location.getLongitude(),location.getLatitude(), getDocLng(doc1), getDocLat(doc1))); String DistanceDoc2 = Double.toString(calculateDistance(location.getLongitude(),location.getLatitude(), getDocLng(doc2), getDocLat(doc2))); return DistanceDoc1.compareToIgnoreCase(DistanceDoc2); – Heretyk Oct 08 '15 at 17:25
  • In fact i managed to Create a List of my objects after my query. But i am wondering how i can sort them from their distance from me... And then sending the List to my adapter. You know what i mean ? – Heretyk Oct 08 '15 at 17:29
  • Hi @Heretyk, why do you convert the Double value to a String? Just use the double for the comparison. String DistanceDoc2 = Double.toString(calculateDistance(location.getLongitude(),location.getLatitude(), getDocLng(doc2), getDocLat(doc2))); – Evgeny Maltsev Oct 15 '15 at 10:07
  • Hi @Evgeny Maltsev : you are right, i figured this out a few days after the initial post :) It is working now. I compared the doubles, sorted my Objects in a Hashmap, then i retrieve my items in the Hasmap to add them to my layout...It is working, but performance has been impacted when loading the ListView. :/ – Heretyk Oct 16 '15 at 15:30
  • Keep having message like `Choreographer: Skipped 808 frames!` , `CursorWindow: CursorWindow::createFromParcel ashmemFd=139, ssize_t=2097152 UNKNOWN_ERROR=1096320745` or `dalvikvm: GC_FOR_ALLOC freed 2627K, 23% free 15158K/19472K, paused 22ms, total 22ms` – Heretyk Oct 16 '15 at 15:31
  • You could try implementing the viewHolder pattern which might improve the performance:[viewholder example](https://dzone.com/articles/android-listview-optimizations). @Heretyk – Evgeny Maltsev Oct 18 '15 at 08:06