隐藏RecyclerView中的视图

Ton*_*ang 37 android

我有这样的代码

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

它映射到一个中的一行RecyclerView.R.id.text实际上是布局的根视图,它在这里被膨胀并传递给构造函数.

我正在使用默认的实现LinearLayoutManager.

bindViewHolder,我调用hide(true)一个实例MyViewHolder,但不是按预期折叠行,该行变得不可见,保持其高度和位置RecyclerView.还有其他人遇到过这个问题吗?

如何隐藏RecyclerView中的项目?

yig*_*git 37

没有内置的方法来隐藏RV中的孩子,但当然如果它的高度变为0,它将不可见:).我假设您的根布局确实有一些最小高度(或精确高度),即使它是GONE,它仍然需要空间.

此外,如果要删除视图,请将其从适配器中删除,不要隐藏它.你有什么理由想隐藏而不是删除吗?


小智 33

put方法setVisibility(boolean isVisible)ViewHolder.

您可以更改itemView参数(宽度和高度)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);
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

并更改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 */    

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这有效,但它会导致大量的回收测量并使滚动变得非常笨拙. (2认同)

Ton*_*ang 10

好吧,所以我最终做到这一点的方式是我拥有了我的整个数据集,myObjects并且我有一些场景我只想显示该数据集的子集.

由于设置行能见度RecyclerView不引起高度崩溃,并设置行的高度没有出现要么做任何事情,我需要做的就是自顾自地称为次要数据集myObjectsShown这只不过是更List<Integer>会index into myObjects以确定将显示哪些对象.

然后我会间歇性地更新myObjectsShown以包含正确的索引.

因此,

public int getItemCount() {
    return myObjectsShown.size();
}
Run Code Online (Sandbox Code Playgroud)

public void onBindViewHolder(MyViewHolder holder, int position) {
    Object myObject = myObjects.get(myObjectsShown.get(position));
    // bind object to viewholder here...
} 
Run Code Online (Sandbox Code Playgroud)

  • 这非常聪明和简单.这应该是最好的答案,因为你真的不必干涉`getItemViewType`或其他任何东西.但它确实可以动态隐藏你不想表现的孩子,并且还可以很好地考虑身高变化. (2认同)

Lạn*_*àng 10

你能行的!

首先,您需要检测要隐藏的项目的哪个位置.您可以自定义getItemViewType来执行此操作.

接下来,在onCreateViewHolder上,取决于视图类型.你可以这样做:

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; 
Run Code Online (Sandbox Code Playgroud)

- >空项是没有任何内容的布局(换句话说,它是创建时的默认布局).或代码:

<?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>
Run Code Online (Sandbox Code Playgroud)

希望它有所帮助!

  • 我认为将`layout_height`设置为`0dp`或`wrap_content`是个好主意,如果你将它设置为`match_parent`,那么每个空单元格将占用父视图的大小...... (3认同)