在回收者视图中跳过项目

Skip items in recycler view

你好,我想跳过 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" />

并且回收者视图是

   @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 的项目。我的逻辑工作项目不可见,但它们留在那里 space。我怎样才能删除项目之间的 spaces。

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

由于您再次将 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);
}
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())           
}

您需要为持有人设置可见性,而不是您的观点。

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

的可见性

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

隐形

This view is invisible, but it still takes up space for layout purposes.

消失

This view is invisible, and it doesn’t take any space for layout purposes.

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())           
}

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

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

我们有 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
 }

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

假设您有一个函数接受位置作为参数,returns 实际位置作为结果

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
 }

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

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

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

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

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

视图持有者:

    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
    }

}

希望对您有所帮助。编码愉快!