I have code like this
public static class MyViewHolder extends RecyclerView.ViewHolder {
@InjectView(R.id.text)
TextView label;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.inject(this, itemView);
}
public void hide(boolean hide) {
label.setVisibility(hide ? View.GONE : View.VISIBLE);
}
}
which maps to a single row in a RecyclerView
. R.id.text
is in fact the root view of the layout that gets inflated and passed in to the constructor here.
I'm using the default implementation of LinearLayoutManager
.
In bindViewHolder
, I call hide(true)
on an instance of MyViewHolder
, but instead of collapsing the row as expected, the row becomes invisible, maintaining its height and position in the RecyclerView
. Has anyone else run into this issue?
How do you hide items in a RecyclerView?
There is no built in way to hide a child in RV but of course if its height becomes 0, it won't be visible :). I assume your root layout does have some min height (or exact height) that makes it still take space even though it is GONE.
Also, if you want to remove a view, remove it from the adapter, don't hide it. Is there a reason why you want to hide instead of remove ?
Put method setVisibility(boolean isVisible)
in ViewHolder
.
You can change itemView
params(width and height) for LayoutManager
:
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
...
public void setVisibility(boolean isVisible){
RecyclerView.LayoutParams param = (RecyclerView.LayoutParams)itemView.getLayoutParams();
if (isVisible){
param.height = LinearLayout.LayoutParams.WRAP_CONTENT;
param.width = LinearLayout.LayoutParams.MATCH_PARENT;
itemView.setVisibility(View.VISIBLE);
}else{
itemView.setVisibility(View.GONE);
param.height = 0;
param.width = 0;
}
itemView.setLayoutParams(param);
}
public ViewHolder(View itemView) {
super(itemView);
...
}
}
and change visibility for ItemDecoration
(Divider):
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
...
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
...
for (int i = 0; i < parent.getChildCount(); i++) {
if (parent.getChildAt(i).getVisibility() == View.GONE)
continue;
/* draw dividers */
}
}
}
You CAN do it!
First, you need to detect which position of item that you want to hide. You can custom getItemViewType to do it.
Next, on onCreateViewHolder, depend on the view type. You can do something like this:
if(viewType == TYPE_HIDE) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.empty_item, parent, false);
vHolder = new ViewHolder(context, v, viewType, this);
break;
}
return vHolder;
-> empty item is a layout that have nothing, (in other word, it is default layout whenever created). or code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
Hope it help!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With