【问题标题】:Sorting a listview of objects with value of the object itself - After a Query in DB使用对象本身的值对对象的列表视图进行排序-在数据库中查询之后
【发布时间】:2015-10-07 15:05:00
【问题描述】:

我正在使用自定义适配器来填充 ListView。 数据是通过我对远程数据库进行的查询来检索的。

我在查询结果的自定义适配器中进行迭代,然后使用notifyDataSetChanged()将每个对象发送到列表视图

对象包含值 String TimeUpdated(DateTime 类)。

我想根据 TimeUpdated 值对列表视图中的对象进行降序排序。

根据我的阅读,在调用“notifyDataSetChanged();”之前,我必须在迭代中执行此操作在我的适配器里面。

但我不知道该怎么做。

如果我的理解是正确的,有人可以分享示例代码吗?

向社区致敬


更新:2015 年 8 月 10 日

我认为我必须根据查询结果的迭代在我的适配器中创建一个 arrayList。

所以我这样做了: 1.我迭代我的查询结果并将每个对象放在一个arrayList中。 所以我有一个包含对象的数组列表。 2.每个对象都有一个包含“纬度,经度”的字符串值。

我想根据它们与我的距离对它们进行排序。

已经可以计算距离了。

我现在不知道如何对列表进行排序?

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();
}

重要:

我使用两个适配器来构造带有查询结果的 ListView。 一个名为 LiveQueryAdapter 的父级,从 BaseAdapter 扩展而来。 而在名为DocumentAdapter...的 Fragment 中的那个扩展自 LiveQueryAdapter

LiveQueryAdapter 类

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 类(我的 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;

    }
}

在我的片段中:

这个适配器在我的 Fragment 的onCreateView() 中被调用,如下所示:

    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);

【问题讨论】:

  • 为什么不将排序作为数据库查询的一部分?
  • 我不能,因为我已经用一些键过滤了,我不能添加另一个排序。
  • 这很有意义...您可以编辑您的问题并添加您当前的适配器代码吗?还有“包含值String TimeUpdated”的类?
  • 我会发布适配器的相关部分。对于类,它没有用。想象一个返回 10 个对象 X 的查询。每个对象都是一个 JSONObject,其中包含一个变量字符串“lastTimeUpdated”。我想对比较“lastTimeUpdated”的结果进行降序排序。
  • @petey :根据要求,我发布了适配器代码。对于您的信息“文档”对象是我要排序的对象:)

标签: android sorting listview android-listview


【解决方案1】:

也许这会有所帮助

   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;
        }
    }

然后你可以调用

myAdapter.setList(list);

这将设置列表并对其进行排序。

排序:

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

取自这里:Android-java- How to sort a list of objects by a certain value within the object

【讨论】:

  • 谢谢。在我的情况下,该列表将是 Objects (not string) 的列表。如何根据其中一个变量的值对“sortMyList()”中的对象进行排序? (一个整数、一个字符串、一个日期等...)
  • 即使我比较的值不是对象的参数,我可以使用它吗? 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,为什么要将Double 值转换为字符串?只需使用双精度进行比较。 String DistanceDoc2 = Double.toString(calculateDistance(location.getLongitude(),location.getLatitude(), getDocLng(doc2), getDocLat(doc2)));
  • 嗨@Evgeny Maltsev:你是对的,我在最初发布几天后发现了这一点:)它现在正在工作。我比较了双打,在 Hashmap 中对我的对象进行了排序,然后我在 Hasmap 中检索我的项目以将它们添加到我的布局中......它正在工作,但在加载 ListView 时性能受到了影响。 ://
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-03
  • 2015-03-30
相关资源
最近更新 更多