I've read a lot of StackOverflow posts about such problem but most of them were not using cursor as their data source for RecyclerView
. But my app does.
In my app, I query the database which gives me results as shown in the following image. Results are ordered by _id column.
I want my RecyclerView
to represents the data something like below:
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
As you can see it forms groups with headings and relevant items go under each heading.
I have created two different layouts.
Heading with an item below it layout
<?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>
Item layout
<?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
On the other hand, my adapter does the following.
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 {
}
}
what I am doing in getItemViewType is I check to see whether the _id column matches the lastGroupId by using position argument that is passed to the method. If it matches I just return the VIEW_TYPE_ITEM, which is the normal item layout.
And if it doesn't match, then it gives us an indication that it is the beginning of another group, so for this case, I return VIEW_TYPE_HEADING.
It works fine but as I get more items the heading and placement of items under groups don't seem to be correct. Sometimes the heading layout goes vanish for some group of items as shown below in the image.
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.
Can you give me any suggestions how should I do this or what can I do to achieve such things in RecyclerView
with Cursor or what are my mistakes?