如何在特定条件下从 Recycler View 中隐藏项目?
How to hide an item from Recycler View on a particular condition?
我正在使用 Firebase Recycler Adapter(Firebase UI 库)来填充 Recycler View。我想在条件下隐藏一个项目(行)。
我有一个包含回收视图的 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,但该行仍为空 space。
有没有什么方法我应该重写来克服这个问题,或者有什么方法可以达到这个结果?
您应该从 UsersViewholder 布局中隐藏所有视图或父视图 xml。
您应该隐藏整个 Viewholder 或每个视图
整个取景器:
itemView.setVisibility(View.GONE);
或每个元素:
view.setVisibility(View.GONE);
但是不要忘记设置它们VISIBLE
否则,你最终会从回收中得到一些奇怪的东西
RecyclerView 中没有隐藏子项的内置方法。
但是您可以在您的适配器中实现此功能。
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
IF
view.setVisibility(View.GONE);
gives you a Blank view
然后按照这个。
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());
}
}
在某些情况下,仅更改可见性属性可能仍会分配为空白 space(由于父视图的填充、边距、内部元素等)。然后更改父视图的高度有帮助:
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 在你滚动时被回收,如果你像这样更改属性并且永远不会 return 它们恢复到它们的自然状态,其他元素将已经隐藏在它们重用的情况下相同的观点。
如果您隐藏了整个 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);
这是一个 recyclerView,所以在 if else 块中同时使用两者,否则您可能会遇到一些意想不到的 UI 问题。
“GONE”不会删除项目占用的space....您可以使用
if (condition) {
item.layoutParams.height = 0
item.layoutParams.width = 0
}
在“onBindViewHolder”中
holder.itemView.setVisibility(View.VISIBLE);现在不工作。我正在使用这个
holder.itemView.findViewById(R.id.card).setVisibility(View.GONE);
您可以轻松地将 ViewHolder 值发送到您的操作函数..
我不推荐将 View 的高度和宽度设置为 0 的答案,因为适配器仍然需要渲染它们,如果隐藏项太多,这会导致延迟,最好更改列表本身,然后发送它到适配器
似乎 RV 在内部缓存了根视图信息,因此更改它的可见性对项目占用 space 没有任何作用。
使用 FrameLayout 包裹 RV 项目视图并将 View.GONE 设置为内部视图。这样占用的space会被正确清空,物品不会显示。
private fun hideShowItemView(itemView: View, toShow: Boolean) {
itemView.isVisible = toShow
itemView.layoutParams.height = if (toShow) ViewGroup.LayoutParams.WRAP_CONTENT else 0
}
- itemView 是 ViewHolder 的一个 ItemView
- toShow 是一个布尔值,用于隐藏或显示 recyclerview 的项目
根据需要在 onBindViewHolder 块中使用以下代码行,
To hide Item : hideShowItemView(holder.itemView, false)
To show Item : hideShowItemView(holder.itemView, true)
我正在使用 Firebase Recycler Adapter(Firebase UI 库)来填充 Recycler View。我想在条件下隐藏一个项目(行)。 我有一个包含回收视图的 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,但该行仍为空 space。
有没有什么方法我应该重写来克服这个问题,或者有什么方法可以达到这个结果?
您应该从 UsersViewholder 布局中隐藏所有视图或父视图 xml。 您应该隐藏整个 Viewholder 或每个视图
整个取景器:
itemView.setVisibility(View.GONE);
或每个元素:
view.setVisibility(View.GONE);
但是不要忘记设置它们VISIBLE
否则,你最终会从回收中得到一些奇怪的东西
RecyclerView 中没有隐藏子项的内置方法。 但是您可以在您的适配器中实现此功能。
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
IF
view.setVisibility(View.GONE);
gives you a Blank view
然后按照这个。
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());
}
}
在某些情况下,仅更改可见性属性可能仍会分配为空白 space(由于父视图的填充、边距、内部元素等)。然后更改父视图的高度有帮助:
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 在你滚动时被回收,如果你像这样更改属性并且永远不会 return 它们恢复到它们的自然状态,其他元素将已经隐藏在它们重用的情况下相同的观点。
如果您隐藏了整个 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);
这是一个 recyclerView,所以在 if else 块中同时使用两者,否则您可能会遇到一些意想不到的 UI 问题。
“GONE”不会删除项目占用的space....您可以使用
if (condition) {
item.layoutParams.height = 0
item.layoutParams.width = 0
}
在“onBindViewHolder”中
holder.itemView.setVisibility(View.VISIBLE);现在不工作。我正在使用这个
holder.itemView.findViewById(R.id.card).setVisibility(View.GONE);
您可以轻松地将 ViewHolder 值发送到您的操作函数..
我不推荐将 View 的高度和宽度设置为 0 的答案,因为适配器仍然需要渲染它们,如果隐藏项太多,这会导致延迟,最好更改列表本身,然后发送它到适配器
似乎 RV 在内部缓存了根视图信息,因此更改它的可见性对项目占用 space 没有任何作用。
使用 FrameLayout 包裹 RV 项目视图并将 View.GONE 设置为内部视图。这样占用的space会被正确清空,物品不会显示。
private fun hideShowItemView(itemView: View, toShow: Boolean) {
itemView.isVisible = toShow
itemView.layoutParams.height = if (toShow) ViewGroup.LayoutParams.WRAP_CONTENT else 0
}
- itemView 是 ViewHolder 的一个 ItemView
- toShow 是一个布尔值,用于隐藏或显示 recyclerview 的项目
根据需要在 onBindViewHolder 块中使用以下代码行,
To hide Item : hideShowItemView(holder.itemView, false)
To show Item : hideShowItemView(holder.itemView, true)