【问题标题】:calculate value based on current and previous row in cursor android根据游标android中的当前行和上一行计算值
【发布时间】:2014-12-31 06:36:27
【问题描述】:

我有一个修改为使用游标设置的回收器适配器,并且我通过加载器等成功地将结果返回到回收器视图。我试图显示当前记录(显示在视图中)和以前的记录(根据位置可能会或可能不会显示在 UI 上)。

当前填充适配器的查询按月显示交易金额。

示例。如果用户选择按月排序,他们将得到以下结果。 (他们也可以按消费金额排序。)

month   |  spending
--------+----------
12/2014 | 123
--------|----------
11/2014 | 145
--------|----------
10/2014 | 130

当用户滚动浏览回收站视图时,显示以下内容的最佳做法是什么?我希望用户能够选择排序类型并根据结果找到与之前记录的差异。

month   |  spending | difference
--------+-----------+------------
12/2014 | 123       | + 22
--------|-----------+------------
11/2014 | 145       | + 15
--------|-----------+------------
10/2014 | 130       | null

我想使用光标的原因是因为我只想根据光标的位置加载结果。有没有一种方法可以重写查询,以便在适配器中呈现数据时无需进行计算就可以得到我想要的结果?

目前适合我但我不想使用的选项:

我已经通过使用数组列表并在创建数组列表期间进行计算得到了我想要的结果,但我担心当用户输入更多数据(我用 1000 个虚拟记录测试)时,最终用户每次数据集更改时都必须等待列表创建并加载到 UI。

请帮助我了解这些场景的最佳实践。

【问题讨论】:

  • 如果您不想一次计算整个事情(加载时间),那么也许您可以使用自定义适配器来填充列表,然后您可以使用请求的项目计算差异位置和位置 1(如果存在)getView()
  • 但在你的情况下,它的位置和位置+1 [2014 年 12 月旁边的差异是支出(11/2014)-支出(12/2014)],对吧?
  • 我忘了提到我正在使用修改为使用光标的回收器适配器。是的,您的假设是正确的,但是如果用户向上滚动,它必须是位置 + 1,如果用户向下滚动,它必须是位置 - 1,因为顶部的视图会在它们从 UI 中消失时被回收。因此,我认为必须有更好的方法。例如重写查询以提供所需的结果,这样我就不必在视图被回收时在适配器中进行计算。
  • 不,你不必检测滚动的方向,它应该是一样的,为了得到相同的结果这是正确的结果,不管滚动的方向是什么,试着做它在 getView() 中,不要忘记检查 (position+1) is not outOfIndex (data.size()>(position+1)) ...
  • 好的,在重新考虑你所说的之后,这是有道理的。它只是位置+1,但是如果在onBindViewHolder期间使用数组列表,您所说的很容易做到。我不确定如何使用光标进行操作。

标签: android android-cursoradapter android-cursor


【解决方案1】:

好的,我想在 cmets 中发布我告诉你的答案。 以某种方式对您有所帮助。

  • 假设您有一个布局文件 custom_row.xml 来表示列表中的每个项目
  • 在此布局中,您有 3 个文本视图,例如 txtDate、txtSpend 和 txtDif:
  • 您的数据列表是一个ArrayList<SpendingItem>,其中SpendingItem 有(日期,花费),在适配器类中它被称为items

那么 getView 将如下所示:

@override
public View getView(int position, View convertView, ViewGroup parent){
        //convertView == null or not, init ViewHolder, setTag or getTag (in case you are usin this approach to recycle views).

        //here comes the calculations:
        holder.txtDate.setText(items.get(position).getDate());
        holder.txtSpend.setText(items.get(position).getSpend() + "");//as getSpend() return int
        if(items.size() > position+1){
            holder.txtDif.setText((items.get(position+1).getSpend() - items.get(position).getSpend()) + "");
        //result is int, to avoid considering this int as a resource int (in strings xml file) or you can use Integer.toString()
        }else{
            holder.txtDif.setText("N/A");
        }

        // some other code ...

        return convertView;
}

编辑: 使用 CursorAdapter:

@Override
public void bindView(View arg0, Context context, Cursor cursor) {
    //here comes the calculations:
    holder.txtDate.setText(cursor.getString(1));
    holder.txtSpend.setText(cursor.getInt(2) + "");
    final int currentSpen = cursor.getInt(2); // conside index 2 is spending value in cursor
    if(cursor.moveToNext()){
        holder.txtDif.setText((cursor.getInt(2) - currentSpen) + "");
        cursor.moveToPrevious();//return to current position so you will not skip a row from cursor
    }else{
        holder.txtDif.setText("N/A");
    }

    // some other code ...
}

【讨论】:

  • 感谢您的帮助。我在最初的帖子中写道,正如您上面建议的那样,我有一个可行的解决方案。我正在通过光标寻求解决方案。所以我不必每次数据库发生变化时都将整个查询结果重新加载到数组列表中,因为当有 500 多条记录时加载适配器需要很长时间。
  • @user3300856 抱歉不理解这种方式,请检查更新的答案,使用自定义 CursorAdapter 添加建议的 sol
  • 谢谢,我会试试这个,希望当用户快速滚动时不会出现性能问题,然后我会回复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多