【问题标题】:Section in RecylerView with CursorRecyclerView 中带光标的部分
【发布时间】:2019-01-25 13:33:47
【问题描述】:

我已经阅读了很多关于此类问题的 StackOverflow 帖子,但其中大多数都没有使用游标作为 RecyclerView 的数据源。但我的应用可以。

在我的应用程序中,我查询了数据库,结果如下图所示。结果按 _id 列排序。

我希望我的RecyclerView 代表如下数据:

White Blood Cell(WBC)
    52 10^9/L 2018-08-15
    52 10^9/L 2018-08-15
    52 10^9/L 2018-08-15

Red Blood Cell - Male
    52 10^9/L 2018-08-15
    52 10^9/L 2018-08-15
    52 10^9/L 2018-08-15

如您所见,它形成了带有标题的组,相关项目位于每个标题下。

我创建了两种不同的布局。

标题下有一个项目

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>
    <TextView
        android:id="@+id/heading"" />
    <LinearLayout>
        <TextView
            android:id="@+id/value" />
        <TextView
            android:id="@+id/date" />
    </LinearLayout>
</LinearLayout>

项目布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout>
    <TextView
        android:id="@+id/value" />
    <TextView
        android:id="@+id/date"/>
</LinearLayout>

忽略布局文件中缺失的细节

另一方面,我的适配器执行以下操作。

public class BloodTestRecordAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    // it holds the _id of the last group    
    private int lastGroupId = -1;

    private final int VIEW_TYPE_HEADING = 0, VIEW_TYPE_ITEM = 1;


    @Override
    public int getItemViewType(int position) {
        int returnItemViewType;

        // get _id value for the row at given position
        int currentGroupId = getCursorAtPosition(position).getInt(0);
        if (currentGroupId != lastGroupId) {
            // return VIEW_TYPE_HEADING
            lastGroupId = currentGroupId;
            returnItemViewType = VIEW_TYPE_HEADING;
        } else {
            returnItemViewType = VIEW_TYPE_ITEM;
        }
        return returnItemViewType;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        RecyclerView.ViewHolder viewHolder;
        View view;
        if (viewType == VIEW_TYPE_HEADING) {
            // inflate HEADING LAYOUT
        } else {
            // inflate item layout
        }
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, Cursor cursor, int position) {

        if (viewHolder.getItemViewType() == VIEW_TYPE_HEADING) {
            // bind values to heading layout
        } else {
            // bind values to item layout
        }
    }

    public class HeadingViewHolder extends RecyclerView.ViewHolder {
    }

    public class ItemViewHolder extends RecyclerView.ViewHolder {
    }

}

我在 getItemViewType 中所做的是通过使用传递给方法的位置参数来检查 _id 列是否与 lastGroupId 匹配。如果匹配,我只返回 VIEW_TYPE_ITEM,这是正常的项目布局。

如果它不匹配,那么它给我们一个指示,它是另一个组的开始,所以对于这种情况,我返回 VIEW_TYPE_HEADING。

它工作正常,但随着我获得更多项目,组下项目的标题和位置似乎不正确。有时,某些项目组的标题布局会消失,如下图所示。

我确定我实现 getViewItemType 的方式不是 正确,我也知道,当我的视图持有者被回收时,它会因为 lastGroupId 变量而与我的 getViewItem 方法混淆

您能否给我任何建议,我该怎么做,或者我可以做些什么来使用光标在RecyclerView 中实现这些目标,或者我的错误是什么?

【问题讨论】:

标签: java android android-recyclerview android-cursor


【解决方案1】:

当您向上滚动 recyclerView 时会出现问题,因此 lastGroupId 无法正确填满。

使用此逻辑代替 getItemViewType 中的当前代码:

if (position == 0) {
    return VIEW_TYPE_HEADING;
} else {
    int currentGroupId = getCursorAtPosition(position).getInt(0);
    int previousGroupId= getCursorAtPosition(position - 1).getInt(0);
    return currentGroupId != previousGroupId ? VIEW_TYPE_HEADING : VIEW_TYPE_ITEM;
}

【讨论】:

  • 是的,这样我就不需要依赖 lastGroupId 变量,它实际上并不代表最后一个组的 id,因为 RecyclerView 会进行优化,lastGroupId 会获取无效的项目值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
  • 2018-10-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多