RecyclerView 中带有光标的部分

Section in RecylerView with Cursor

我已经阅读了很多关于此类问题的 Whosebug 帖子,但大多数帖子都没有使用游标作为 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>

Ignore missing details in layout files

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

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 匹配。如果它匹配我只是 return VIEW_TYPE_ITEM,这是正常的项目布局。

如果不匹配,则表明它是另一组的开始,因此对于这种情况,我 return VIEW_TYPE_HEADING.

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

I know for sure that the way i implemented the getViewItemType is not correct, I also know as my viewholders get recycled it messes with my getViewItem method because of that lastGroupId variable.

你能给我一些建议吗,我应该怎么做,或者我可以做些什么来在 RecyclerView 中用 Cursor 实现这样的事情,或者我的错误是什么?

当您向上滚动 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;
}