如何隐藏一个项目从回收视图在一个特定的条件?

我使用 Firebase 回收器适配器(Firebase UI 库)填充回收器视图。我想隐藏一个条件的项(行)。 我有一个包含回收视图的 LinearLayout。

我在回收器视图适配器的 populateViewHolder()方法中将线性布局可见性设置为 Gone。

@Override
protected void populateViewHolder(UsersViewHolder viewHolder, User user, int position) {


if (user.getUserEmail().equals(Utils.decodeEmail(userEmail))) {
viewHolder.llMain.setVisibility(View.GONE);
return;
}


viewHolder.tvUserEmail.setText(user.getUserEmail());
}

它隐藏了 LinearLayout,但是该行仍然保留了空白。

有没有什么方法可以克服这个问题,或者有什么方法可以达到这个结果?

93379 次浏览

应该隐藏 UsersViewholder 布局 xml 中的所有视图或父视图。 应该隐藏整个视图持有者或每个视图

全体观众:

itemView.setVisibility(View.GONE);

或每个元素:

view.setVisibility(View.GONE);

但是不要忘记设置它们 VISIBLE否则,你将结束一些奇怪的东西从回收利用

回收视图中没有隐藏子节点的内置方式。 但是您可以在适配器中实现这个特性。

public class MyAdapter extends RecyclerView.Adapter<...>{
List<Object> items;
Map<Integer,Object> deletedItems;
...


public void hideItem(final int position) {
deletedItems.add(position, items.get(position));
items.remove(position);
notifyItemRemoved(position);
}


....
}
public class OfferViewHolder extends RecyclerView.ViewHolder {
public TextView textViewOfferName;
public LabelImageView labelImageView;
public TextView textViewOldPrice;
public TextView textViewNewPrice;
public TextView textViewShopName;
public TextView textViewTimeDate;
public TextView textViewDistance;


public LinearLayout linearLayoutMain;




public OfferViewHolder(View view) {
super(view);
linearLayoutMain=(LinearLayout) view.findViewById(R.id.ll_main);
textViewOfferName = (TextView) view.findViewById(R.id.textViewoffername);
labelImageView=(LabelImageView) view.findViewById(R.id.labelImageView) ;
textViewOldPrice=(TextView) view.findViewById(R.id.textViewOldPrice);
textViewNewPrice=(TextView) view.findViewById(R.id.textViewNewPrice);
textViewShopName=(TextView) view.findViewById(R.id.textViewShopName);
textViewTimeDate=(TextView) view.findViewById(R.id.textViewDate);
textViewDistance=(TextView) view.findViewById(R.id.textViewDistance);


linearLayoutMain.setVisibility(View.GONE);
textViewOfferName.setVisibility(View.GONE);
labelImageView.setVisibility(View.GONE);
textViewOldPrice.setVisibility(View.GONE);
textViewNewPrice.setVisibility(View.GONE);
textViewShopName.setVisibility(View.GONE);
textViewTimeDate.setVisibility(View.GONE);
textViewDistance.setVisibility(View.GONE);






}




}`enter code here`

然后在你的适配器里

 if (a.equals(offer.getOfferCategory())) {




if (offer.getOfferCategory()==null){
//                            chatMessageViewHolder.getLinearLayoutMain().setVisibility(View.GONE);
//                            chatMessageViewHolder.linearLayoutMain.setLayoutParams(new RecyclerView.LayoutParams(0, 0));




}
else {
chatMessageViewHolder.itemView.setVisibility(View.VISIBLE);
chatMessageViewHolder.textViewShopName.setText(offer.getOfferCategory());
chatMessageViewHolder.linearLayoutMain.setVisibility(View.VISIBLE);
chatMessageViewHolder.textViewOfferName.setVisibility(View.VISIBLE);
chatMessageViewHolder.labelImageView.setVisibility(View.VISIBLE);
chatMessageViewHolder.textViewOldPrice.setVisibility(View.VISIBLE);
chatMessageViewHolder.textViewNewPrice.setVisibility(View.VISIBLE);
chatMessageViewHolder.textViewShopName.setVisibility(View.VISIBLE);
chatMessageViewHolder.textViewTimeDate.setVisibility(View.VISIBLE);
chatMessageViewHolder.textViewDistance.setVisibility(View.VISIBLE);


}

谢谢你 Lorescu George C T Lin 和 Dhalav

如果

view.setVisibility(View.GONE);

给你一个空白的视角

那就跟着这个。

public static class Data_ViewHolder extends RecyclerView.ViewHolder {
private final LinearLayout layout;
final LinearLayout.LayoutParams params;


public Show_Chat_ViewHolder(final View itemView) {
super(itemView);
.
.
.
layout =(LinearLayout)itemView.findViewById(R.id.show_item_layout);
params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
.
.
.
}


private void Layout_hide() {
params.height = 0;
//itemView.setLayoutParams(params); //This One.
layout.setLayoutParams(params);   //Or This one.


}
}

现在从 适配器呼叫

mFirebaseAdapter = new FirebaseRecyclerAdapte......{
public void populateViewHolder.....{


if(model.getData().equals("..Something.."))
{
viewHolder.Layout_hide();
}
else
viewHolder.Person_Email(model.getEmail());
}
}

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

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 在您滚动时会被回收,如果您将属性更改为这样,并且永远不会返回它们的自然状态,那么其他元素将在它们重用相同视图的情况下已经被隐藏。

如果您正在隐藏整个 itemView,并且面临空格的问题。

尝试隐藏 itemView。

holder.itemView.setVisibility(View.GONE);
ViewGroup.LayoutParams params = holder.itemView.getLayoutParams();
params.height = 0;
params.width = 0;
holder.itemView.setLayoutParams(params);

还有这个。

holder.itemView.setVisibility(View.VISIBLE);

这是一个回收视图,因此在 if else 块中同时使用它们,否则可能会遇到一些意想不到的 UI 问题。

“ GONE”不会移除该物品所占用的空间... ... 您可以使用

if (condition) {
item.layoutParams.height = 0
item.layoutParams.width = 0
}

在“ onBindViewHolder”中

SetVisiability (View.VISIBLE) ; 现在不工作

FindViewById (R.id.card) . setVisiability (View.GONE) ;

您可以很容易地将 ViewHolder 值发送到您的操作函数。

我不推荐将 View 的高度和宽度设置为0的答案,因为适配器仍然需要呈现它们,如果有太多的隐藏项可能导致延迟,最好更改列表本身,然后将其发送给适配器

看起来 RV 在内部缓存根视图信息,所以改变它的可见性对项目占用的空间没有任何影响。

用 FrameLayout 包装您的 RV 项目视图,并将 View.GONE 设置为内部视图。这种方式占用的空间将被正确清除,以及项目将不会显示在所有。

private fun hideShowItemView(itemView: View, toShow: Boolean) {
itemView.isVisible = toShow
itemView.layoutParams.height = if (toShow) ViewGroup.LayoutParams.WRAP_CONTENT else 0
}
  1. ItemView 是 ViewHolder 的一个 ItemView
  2. ToShow 是一个用于隐藏或显示回收视图项的布尔值

根据要求使用 onBindViewHolder 块中的以下代码行,

To hide Item : hideShowItemView(holder.itemView, false)


To show Item : hideShowItemView(holder.itemView, true)