【问题标题】:Skip items in recycler view跳过回收站视图中的项目
【发布时间】:2018-03-16 21:28:08
【问题描述】:

您好,我想跳过recyclerview 中的一些项目。

下面是代码

item_Data.xml

 <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:id="@+id/mainlayout"
android:layout_height="wrap_content">
<ImageView
    android:visibility="gone"
    android:id="@id/image"
    android:layout_gravity="center"
    android:layout_width="100dp"
    android:layout_height="100dp" />
<TextView
    android:visibility="gone"
    android:textStyle="bold"
    android:id="@id/title"
    android:layout_gravity="center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:maxLength="15" />

而recycler view是

   @Override
public void onBindViewHolder(final MovieViewHolder holder, final int position) {
    String download= news.get((position)).getDownloadLinkForApkNew();
    String desc_new = news.get(position).getApkJData();
    if (download.isEmpty()==false && desc_new.isEmpty()==false) {
        holder.movieTitle.setVisibility(View.VISIBLE);
        holder.imageView.setVisibility(View.VISIBLE);
        Picasso.with(context).load(news.get((position)).getBetterFeaturedImage().getSourceUrl()).into(holder.imageView);
        holder.movieTitle.setText(news.get(position).getTitle().getRendered());
    }

我不想要没有下载和 desc_new 的项目。我的逻辑工作项不可见,但它们留有空间。如何删除项目之间的空格。

【问题讨论】:

  • holder.itemview.setVisibility(GONE)
  • RecyclerView 的每一项都有LinearLayout 吗?
  • 尝试这样的操作从数组列表中删除项目if (download.isEmpty()==true &amp;&amp; desc_new.isEmpty()==true) { remove this item from array list }
  • 您可以在显示数据集合中的项目之前删除。

标签: android layout android-recyclerview recyclerview-layout


【解决方案1】:

有一个非常简单的解决方法:

如果您在将视图绑定到 ViewHolder 时对视图执行view.setVisibility(View.GONE);,则视图将被隐藏,但视图应该在的位置仍然有一个空间; 因此,这种方法效率不高

那么我们如何解决这个问题呢?

您需要做的就是将要隐藏的视图的高度和/或宽度设置为零。这是实现此目的的简单方法:

查看持有人:

    public class MyViewHolder extends RecyclerView.ViewHolder{

        public LinearLayout.LayoutParams params;
        public LinearLayout rootView //the outermost view from your layout. Note that it doesn't necessarily have to be a LinearLayout.

        //todo: Don't forget to add your other views

        public MyViewHolder(View itemView){
            super(itemView);

            params = new LinearLayout.LayoutParams(0, 0);
            rootView = itemView.findViewById(R.id.rootView);

            //todo: Don't forget to initialize your views


        }

    }

onBindViewHolder:

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position){

    if(your_condition){
        holder.rootView.setLayoutParams(holder.params);  
        //this line hides the view completely
    }
    else{
        //todo: Do your regular stuff
    }

}

我希望这会有所帮助。编码愉快!

【讨论】:

    【解决方案2】:
    if (download.isEmpty()==true && desc_new.isEmpty()==true) {
    
            //Hide the items
       holder.movieTitle.setVisibility(View.GONE);
       holder.imageView.setVisibility(View.GONE);
    
    }else {
       holder.movieTitle.setVisibility(View.VISIBLE);
       holder.imageView.setVisibility(View.VISIBLE);
       Picasso.with(context).load(news.get((position)).getBetterFeaturedImage().getSourceUrl()).into(holder.imageView);
       holder.movieTitle.setText(news.get(position).getTitle().getRendered())           
    }
    

    【讨论】:

    • 但是空格不去
    • 你必须使用 view.GONE 而不是 view.INVISIBLE
    • 在 XML 中使用去
    【解决方案3】:

    您需要为您的持有者设置可见性,而不是您的视图。

    if (download.isEmpty()==true && desc_new.isEmpty()==true) {
      holder.setVisibility(View.GONE);
    
    }else {
       holder.setVisibility(View.VISIBLE);
       Picasso.with(context).load(news.get((position)).getBetterFeaturedImage().getSourceUrl()).into(holder.imageView);
       holder.movieTitle.setText(news.get(position).getTitle().getRendered())           
    }
    

    同时从您的 xml 中删除可见性

    【讨论】:

    • RecyclerView.ViewHolder中没有setVisibility(int)这样的方法。
    【解决方案4】:

    让我们深入了解回收站视图的工作原理

    我们有 2 个函数 onCreateView 和 onBindview。由于函数的名称很容易解释 onCreateView 创建视图,而 onBindView 获取创建的视图并将数据绑定到其中

    现在让我们假设整个视图类型相似,并且您使用对象数组或光标来填充整个视图。

    所以在 bindView 中,为了获取数据,您必须使用过任一

     cursor.moveToPosition(position)
    

     mList.get(position)
    

    正如您所见,绑定是根据我们从 onBindView 参数获得的位置发生的

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
         //mList.get(position) or cursor.moveToPosition
     }
    

    因此您可以使用这些知识来专门跳过视图绑定

    假设你有一个接受位置作为参数并返回实际位置作为结果的函数

    private int getActualPostion(int position){
         //your logic to skip the given postion 
         //say  if(position == 4){return postion+2}
    }
    

    所以你可以实现这样的东西

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
           mList.get(getActualPosition(position));
     }
    

    这将允许您跳过那些不显示的视图

    最后在 getCount 方法中,recycler view 使用它来决定视图的数量

     @Override
     public int getItemCount() {
         //foreach in array { if(already downloaded) i++} 
         // return array.size - i
     }
    

    我希望这会有所帮助 这也将为您提供更大的灵活性,您可以添加更多过滤器并使用相同的数据集......更轻松地跳过视图

    【讨论】:

    • 我不想隐藏特定项目。我想隐藏所有不符合我上述条件的项目。因为我从服务器获取数据。回收站视图按照您的解释获取数据的位置并显示它。我让一些物品通过支票消失了。它们没有显示在用户界面中,但项目有空格\@Tushar Saha
    • 它不会隐藏这些项目...它会跳过这些项目,因为 bindview 无法访问它们,因此也不会有任何空格,请确保正确实现 getPosition 函数
    • 什么是光标
    【解决方案5】:

    您可以从 arraylist 中删除项目,然后通过这种方式将更新的数组列表传递给适配器,您无需使用视图的可见性

    【讨论】:

      【解决方案6】:

      通过将它们设为View.INVISIBLE,您并没有删除保留的空间。相反,您可以使用View.GONE 使它们不可见并允许占用保留的空间。

      由于您再次设置 Views 可见,您必须使用 if-else 子句撤消它,例如

      if (!download.isEmpty() && !desc_new.isEmpty()) {
          // make visible
      } else {
          // make invisible with gone e.g.
          holder.movieTitle.setVisibility(View.GONE);
          holder.imageView.setVisibility(View.GONE);
      }
      

      【讨论】:

      • 不要使用已消失的使用隐形
      • @Shahrozjavaid 你在哪里做的?你在 else 分支中设置为gone 了吗?
      • 不,我在 xml 中设置了它。你可以看到上面的xml。 @MuratK。
      • @Shahrozjavaid 是的,这就是为什么您必须在 else 分支中再次将其设置为 gone 的原因。请按照我的回答去做。
      【解决方案7】:

      您应该使用 View.GONE 而不是 View.INVISIBLE

      不可见

      这个视图是不可见的,但它仍然占用空间用于布局。

      过去了

      这个视图是不可见的,它不占用任何布局空间。

      if (download.isEmpty()==true && desc_new.isEmpty()==true) {
      
             holder.movieTitle.setVisibility(View.GONE);
             holder.imageView.setVisibility(View.GONE);
      
      }else {
         holder.movieTitle.setVisibility(View.VISIBLE);
         holder.imageView.setVisibility(View.VISIBLE);
         Picasso.with(context).load(news.get((position)).getBetterFeaturedImage().getSourceUrl()).into(holder.imageView);
         holder.movieTitle.setText(news.get(position).getTitle().getRendered())           
      }
      

      【讨论】:

      • @Shahrozjavaid 尝试这样的操作从数组列表中删除项目if (download.isEmpty()==true &amp;&amp; desc_new.isEmpty()==true) { remove this item from array list }
      • 我想隐藏除我调节之外的所有内容。项目未显示。回收站视图中有空格。我试图解决你建议的问题。
      猜你喜欢
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多