【问题标题】:Visibility gone in recyclerview still occupies spaces?recyclerview 中的可见性消失了仍然占据空间?
【发布时间】:2019-08-02 14:31:49
【问题描述】:

这是我当前的代码。我想在我的recyclerview 上隐藏一个特定的项目,但是当我使用visibility.gone 时,仍然会占用recyclerview 上的空间。我也尝试了所有可能的解决方案How to hide an item from Recycler View on a particular condition?任何帮助

  for(int j =0; j < minusList.size(); j++){
      int availableRooms =  minusList.get(j);

      if(norooms > availableRooms){ //norooms is the number of rooms wanted
      holder.itemView.setVisibility(View.GONE);
      mAdapter.notifyItemRemoved(position);
     }else{
      holder.rRoomsLeft.setText("Room available");
     }

}

这是我的 XML

<android.support.v7.widget.RecyclerView
                android:id="@+id/listView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:focusable="false"
                android:focusableInTouchMode="false" />

【问题讨论】:

  • 最好发布您的回收站项目单元格 XML 代码
  • @DhavalSolanki 编辑了我的帖子
  • 其实我要的是cell XML,意思是你用来显示单行的布局。
  • holder.itemView.setVisibility(View.GONE); 有什么用,你叫notifyItemRemoved 吗?如果项目被删除,那么它的可见性就无关紧要了.,..我也不知道你到底在哪里调用这段代码。提供minimal reproducible example
  • 如果我把我的整个代码太多了如果你想要每个细节哈哈。

标签: android android-recyclerview


【解决方案1】:

请试试这个

    for(int j =0; j < minusList.size(); j++){

      int availableRooms =  minusList.get(j);

      if(norooms > availableRooms){        //norooms is the number of rooms wanted
        holder.itemView.setVisibility(View.GONE);
        mAdapter.notifyItemRemoved(position); 
     }else{
         holder.itemView.setVisibility(View.VISIBLE);
         holder.rRoomsLeft.setText("Room available");
     }
}

【讨论】:

    【解决方案2】:

    我猜你说“占用空间”是因为行在那里但没有显示“可用房间”。

    从 RecyclerView 中删除一行是通过首先从下划线列表中删除它并调用 notifyItemRemoved 或 notifyDatasetChanged 来完成的,而不是通过隐藏行的视图。

    在您的情况下,您需要先从 minusList 中删除项目,然后调用 notifyItemRemoved,否则如果 getItemCount() 仍然返回 minusList.size,RecyclerView 仍然认为行存在,即使它不可见。

    【讨论】:

    • 我从 firebase 检索数据与 minusList 无关,这是不同的数据
    【解决方案3】:

    不要使用holder.itemView.setVisibility(View.GONE);,而是使用这个:

      ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
      params.height = 0;
      holder.itemView.setLayoutParams(params);
    

    【讨论】:

    • 这应该是公认的解决方案,至少它对我有用
    • 这种方法的问题是,如果您在项目之间有一个ItemDecoration,那么您在删除项目之前和之后仍然会有分隔符。
    【解决方案4】:
    ViewGroup.LayoutParams params = chatsViewHolder.itemView.getLayoutParams();
    params.height = 0;
    chatsViewHolder.itemView.setLayoutParams(params);
    

    【讨论】:

      【解决方案5】:

      1.为什么会这样?

      holder.itemView.setVisibility(View.GONE); 这在 RecyclerView 中不起作用。

      itemView 是 RecyclerView 中的子视图。与其他 ViewGroup(FrameLayout 等)不同,RecyclerView 在布局过程中忽略了 child 的可见性。

      2.如何解决?

      Option1 使用 FrameLayout 等常规视图组来包裹您的真实布局,并隐藏您的真实布局:findViewById(R.id.layout_to_hide).setVisibility(View.GONE)

      <FrameLayout android:layout_width="match_parent"
          android:layout_height="wrap_content">
      
          <LinearLayout android:id="@+id/layout_to_hide"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content">
               //Put here your views
          </LinearLayout>
      </FrameLayout>
      

      Option2 将 itemView 的高度改为 0,这样我们就看不到了

      holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
      

      Option3如果该项目不应该在列表中,那么就不要让它进入适配器数据,或者将其删除。

      3.了解更多

      1.为什么其他视图组(例如 FrameLayout)可以很好地处理儿童的可见性?

      如果孩子的布局参数已经消失,他们不会计算孩子的布局参数

      2。为什么 RecyclerView 没有?

      RecyclerView 仍然会计算孩子的布局参数,如果它已经消失,所以它仍然占用空间。

      【讨论】:

        【解决方案6】:

        在某些情况下,仅更改可见性属性可能仍会以分配的空白空间结束(因为父视图的填充、边距、内部元素等)。然后更改父视图的高度会有所帮助:

        holder.itemView.setVisibility(View.GONE); 
        holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0, 0));
        

        然后确保在它应该可见的条件下,也设置:

        holder.itemView.setVisibility(View.VISIBLE);
        holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        

        您需要这样做,因为 viewHolder 在您滚动时会被回收,如果您像这样更改属性并且从不将它们返回到它们的自然状态,那么如果其他元素重用相同的视图,它们将已经被隐藏。

        【讨论】:

          猜你喜欢
          • 2013-09-13
          • 2018-02-26
          • 2021-04-04
          • 2018-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-02
          相关资源
          最近更新 更多