How to handle expandable ViewHolders in a RecyclerView?
You should not iterate all views. You need just save index of expanded view and call notifyDataSetChanged
or notifyItemChanged
.
private int expandedItemIndex = -1;
@Override
protected void onBindViewHolder(@NonNull BrewViewHolder holder,
final int position, @NonNull Brew brew) {
// Bind Views
holder.bind(brew);
// Set expander ClickListener
holder.card.setOnClickListener(v -> {
if (position == expandedItemIndex) {
notifyItemChanged(position);
expandedItemIndex = -1;
} else {
if (expandedItemIndex != -1) {
notifyItemChanged(expandedItemIndex);
}
expandedItemIndex = position;
notifyItemChanged(position);
}
});
if (position == expandedItemIndex) {
// Expand
holder.quickActions.setVisibility(View.VISIBLE);
} else {
// Collapse
holder.quickActions.setVisibility(View.GONE);
}
}
Recyclerview expand/collapse a number of items
This should be easy to do right within your adapter.
Add a flag to your adapter class:
private boolean mExpanded;
Add a new method to call when the button is clicked:
public void setExpanded(boolean expanded) {
mExpanded = expanded;
notifyDataSetChanged();
}Then modify your
getItemCount
method something like this:@Override
public int getItemCount() {
return mExpanded ? itemlist.size() : 3;
}
It doesn't matter that the rest of the items are still in the adapter list; if you tell the RecyclerView
there are only three items, then that's all it will show.
Expand/collapse a nested RecyclerView
Instead of having a new sub Recyclerview
for every header you can create a multi view-type adapter that will have a view-type for your header and a view-type for your child-item.
And instead of using a just the header data-item for your list of data, use a generic type that will allow casting each data-type to its own view-type.
To do that we need to create an empty interface that all of our data-types will implement that way they are all generic.
public interface GenericDataType {}
so then your data-type will look like this
class HeaderItem implements GenericDataType {
//All of your pojo data
List<ChildrenItem> childrens; //ChildrenItem will also implement the GenericDataType that way both of the items are acceptable
}
So ones we did that we can replace the current items from
private List<EligibilityDetails> mEligsList;
private List<Items> mItemslist;
To
private List<GenericDataType> adapterItems;
Now we need to make sure that whenever we have a certain ViewHolder
the item of that position will be of the right type. In order to do that we need to change our getItemViewType
@Override
public int getItemViewType(int position) {
GenericItem currentItem = adapterItems.get(position);
if (currentItem instanceOf HeaderItem) { //We have to use if else becasue java's switch does not supprt checking instancesOf
return R.layout.your_header_item_layout_id;
} else if(currentItem instanceOf ChildrenItem) {
return R.layout.your_children_item_layout_id;
} else if(repeat for any other types you have) {
return R.layout.your_other_item_layout_id;
} else {
throw new Throwable("Unsupported type"); //This should never happen but we add it to make the compiler compile
}
}
Now we can finally change our onBind
method to support both types
@Override
public void onBindViewHolder(@NonNull final EligibilityAdapter.ViewHolder viewHolder, int i) {
if (viewHolder instanceOf HeaderViewHolder) {
HeaderViewHolder holder = (HeaderViewHolder) viewHolder;
headerItem = (HeaderItem) items.get(i);
//Do rest of binding here
holder.viewToAddMoreItems.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!headerItem.isEpanded()) { //Add to your header type a Boolean to check if it is expanded or not
adapterItems.addAll(headerItem.getChildrens()); //They are the same generic type but the getItemViewType will handle it for us
notifyItemRangeInserted(); //Provied item start index and size of the list
} else {
adapterItems.removeAll(headerItem.getChildrens());
notifyItemRangeRemoved(); I don't remember what it require but you'll figure that out
}
headerItem.setExpanded(!headerItem.isExpanded()); //Flipping the value
}
});
} else if (viewHolder instanceOf ChildrenViewHolder) {
ChildrenViewHolder holder = (ChildrenViewHolder) viewHolder;
childrenItem = (ChildrenItem) items.get(i);
//Do your binding here
} else if(repeate for other view-types) {}
}
Related Topics
Include .So Library in APK in Android Studio
Disabling the Fullscreen Editing View for Soft Keyboard Input in Landscape
Deleting a Gallery Image After Camera Intent Photo Taken
Material Effect on Button with Background Color
How to Display Toast in Android
How to Make an Alert Dialog Fill 90% of Screen Size
Difference Between App:Srccompat and Android:Src in Android's Layout Xml
Android Read Text Raw Resource File
Android: Coloring Part of a String Using Textview.Settext()
Default Firebaseapp Is Not Initialized
How to Create a Custom Navigation Drawer in Android
How to Determine Android Physical Screen Height in Cm or Inches
Firebase Firestore Variable Name Changed
Difference Between Fragmentpageradapter and Fragmentstatepageradapter