RecyclerView 一次为所有项目调用 onCreateViewHolder 和 onBindViewHolder

Posted

技术标签:

【中文标题】RecyclerView 一次为所有项目调用 onCreateViewHolder 和 onBindViewHolder【英文标题】:RecyclerView calling onCreateViewHolder and onBindViewHolder for all items at once 【发布时间】:2017-03-05 12:00:12 【问题描述】:

我有一个 recyclerView 能够在屏幕上显示最多 3 个项目,但它同时为列表中的所有 45 个项目调用 onCreateViewHolder 和 onBindViewHolder(如下面的 LOG 中所示)。

难道不应该只在我将这些项目滚动到屏幕时才调用这些方法吗?

*我正在使用一个包含 0 和 1 的列表作为测试来定义它应该使用哪种布局。

我的适配器代码

public class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> 

int[] post_list;
private static final int TYPE_0 =0;
private static final int TYPE_1=1;
private LayoutInflater inflater;
private Context context;
Activity mActivity;

public MyRecyclerAdapter(Context context, int[] list, Activity mActivity)
    this.context=context;
    inflater=LayoutInflater.from(context);
    this.list=list;
    this.mActivity = mActivity;


@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 
    Log.e("onCreateViewHolder", "CALLED");
    if(viewType== TYPE_0)
        View view=inflater.inflate(R.layout.layout_type0, parent,false);
        Type0Holder holder=new Type0Holder(view);
        return holder;
    
    else
        View view=inflater.inflate(R.layout.layout_type1, parent,false);
        Type1Holder holder=new Type1Holder (view);
        return holder;
    




@Override
public int getItemViewType(int position) 
    if(list[position]==0) 
        return TYPE_0;
    
    else 
        return TYPE_1;
    


@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) 
    if(holder instanceof Type0Holder)
        Type0Holder type0Holder = (Type0Holder) holder;
        type0Holder .mTextView.setText("Layout type 0");
        Glide.with(mActivity.getApplicationContext()).load(R.drawable.imageTest).into(type0Holder.mImageView);
    
    else
        Type1Holder type1Holder = (Type1Holder ) holder;
        type1Holder .mTextView.setText("Layout type 1");
        Glide.with(mActivity.getApplicationContext()).load(R.drawable.imageTest).into(type1Holder.mImageView);
    
    Log.e("onBindViewHolder", String.valueOf(position));



@Override
public int getItemCount() 
    return post_list.length;


class Type0Holder extends RecyclerView.ViewHolder 
    TextView mTextView;
    ImageView mImageView;

    public Type0Holder (View view) 
        super(view);
        mTextView= (TextView) itemView.findViewById(R.id.text_view0);
        mImageView= (ImageView) itemView.findViewById(R.id.image_view0);

    


class Type1Holder extends RecyclerView.ViewHolder 
    TextView mTextView;
    ImageView mImageView;

    public ImagePostHolder(View itemView) 
        super(itemView);
        mTextView= (TextView) itemView.findViewById(R.id.text_view1);
        mImageView= (ImageView) itemView.findViewById(R.id.image_view1);
    

我的回收站 xml

  <android.support.v4.widget.NestedScrollView
    android:id="@+id/nested_scroll_view"
    android:layout_
    android:layout_
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:fillViewport="true"
    android:paddingBottom="3dp"
    >


    <RelativeLayout
        android:layout_
        android:layout_
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:orientation="vertical"
        android:clipToPadding="false">


        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_
            android:layout_
            ></android.support.v7.widget.RecyclerView>


    </RelativeLayout>



</android.support.v4.widget.NestedScrollView>

我的 LOG 显示它正在一次调用所有项目,即使是那些不可见的项目。

10-23 15:15:46.093 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.113 28766-28766/com.example..E/HOLDER: 0
10-23 15:15:46.113 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.113 28766-28766/com.example..E/HOLDER: 1
10-23 15:15:46.113 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.123 28766-28766/com.example..E/HOLDER: 2
10-23 15:15:46.123 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.123 28766-28766/com.example..E/HOLDER: 3
10-23 15:15:46.123 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.133 28766-28766/com.example..E/HOLDER: 4
10-23 15:15:46.133 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.133 28766-28766/com.example..E/HOLDER: 5
10-23 15:15:46.143 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.143 28766-28766/com.example..E/HOLDER: 6
10-23 15:15:46.143 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.143 28766-28766/com.example..E/HOLDER: 7
10-23 15:15:46.153 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.153 28766-28766/com.example..E/HOLDER: 8
10-23 15:15:46.153 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.153 28766-28766/com.example..E/HOLDER: 9
10-23 15:15:46.163 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.163 28766-28766/com.example..E/HOLDER: 10
10-23 15:15:46.163 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.163 28766-28766/com.example..E/HOLDER: 11
10-23 15:15:46.173 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.173 28766-28766/com.example..E/HOLDER: 12
10-23 15:15:46.173 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.183 28766-28766/com.example..E/HOLDER: 13
10-23 15:15:46.183 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.183 28766-28766/com.example..E/HOLDER: 14
10-23 15:15:46.183 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.183 28766-28766/com.example..E/HOLDER: 15
10-23 15:15:46.193 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.193 28766-28766/com.example..E/HOLDER: 16
10-23 15:15:46.193 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.193 28766-28766/com.example..E/HOLDER: 17
    10-23 15:15:46.203 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.203 28766-28766/com.example..E/HOLDER: 18
10-23 15:15:46.203 28766-28766/com.example..E/CREATE HOLDER: CALLED
10-23 15:15:46.213 28766-28766/com.example.. E/HOLDER: 19
    10-23 15:15:46.213 28766-28766/com.example.. E/CREATE HOLDER: CALLED
    10-23 15:15:46.213 28766-28766/com.example.. E/HOLDER: 20
    10-23 15:15:46.213 28766-28766/com.example.. E/CREATE HOLDER: CALLED
    10-23 15:15:46.213 28766-28766/com.example.. E/HOLDER: 21
10-23 15:15:46.223 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.223 28766-28766/com.example.. E/HOLDER: 22
10-23 15:15:46.223 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.233 28766-28766/com.example.. E/HOLDER: 23
10-23 15:15:46.233 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.233 28766-28766/com.example.. E/HOLDER: 24
10-23 15:15:46.233 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.233 28766-28766/com.example.. E/HOLDER: 25
10-23 15:15:46.243 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.243 28766-28766/com.example.. E/HOLDER: 26
10-23 15:15:46.243 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.243 28766-28766/com.example.. E/HOLDER: 27
10-23 15:15:46.253 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.253 28766-28766/com.example.. E/HOLDER: 28
10-23 15:15:46.253 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.253 28766-28766/com.example.. E/HOLDER: 29
10-23 15:15:46.263 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.263 28766-28766/com.example.. E/HOLDER: 30
10-23 15:15:46.263 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.263 28766-28766/com.example.. E/HOLDER: 31
10-23 15:15:46.273 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.283 28766-28766/com.example.. E/HOLDER: 32
10-23 15:15:46.283 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.283 28766-28766/com.example.. E/HOLDER: 33
10-23 15:15:46.293 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.313 28766-28766/com.example.. E/HOLDER: 34
10-23 15:15:46.313 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.323 28766-28766/com.example.. E/HOLDER: 35
10-23 15:15:46.323 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.323 28766-28766/com.example.. E/HOLDER: 36
10-23 15:15:46.333 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.333 28766-28766/com.example.. E/HOLDER: 37
10-23 15:15:46.333 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.343 28766-28766/com.example.. E/HOLDER: 38
10-23 15:15:46.343 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.343 28766-28766/com.example.. E/HOLDER: 39
10-23 15:15:46.343 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.353 28766-28766/com.example.. E/HOLDER: 40
10-23 15:15:46.353 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.353 28766-28766/com.example.. E/HOLDER: 41
10-23 15:15:46.353 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.363 28766-28766/com.example.. E/HOLDER: 42
10-23 15:15:46.363 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.363 28766-28766/com.example.. E/HOLDER: 43
10-23 15:15:46.373 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.373 28766-28766/com.example.. E/HOLDER: 44
10-23 15:15:46.373 28766-28766/com.example.. E/CREATE HOLDER: CALLED
10-23 15:15:46.383 28766-28766/com.example.. E/HOLDER: 45

更新 1 - 我发现我的 recyclerView 不回收的原因是因为它在 NestedScrowView 内,那么即使它在 NestedScrowView 内,我如何让它回收视图?

【问题讨论】:

您找到解决方案了吗? @PedroMazarini 你找到解决方案了吗? @Midhilaj 我实际上不记得我是如何解决这个问题的,已经有一段时间了。无论如何,我一直在使用 Android,如果有什么可以帮助您的,请告诉我。 【参考方案1】:

我遇到了同样的问题。在我的情况下,NestedScrollView 是 Bottom Sheet 的根,我将其替换为 FrameLayout,并且它起作用了。

如果可以,您应该尝试使用FrameLayout

【讨论】:

在我的情况下,我需要使用 NestedScroll 。如何摆脱这种情况?【参考方案2】:

当您将 recyclerview 的高度设置为 wrap-content 时,它会构建一次所有子视图,因为 NestedScrollView 内的 recyclerview 没有任何兄弟,您可以删除 NestedScrollVeiw 并进行如下布局:

<android.support.v7.widget.RecyclerView
        android:id="@+id/recycler"
        android:layout_
        android:layout_
        app:layout_behavior="@string/appbar_scrolling_view_behavior" 
        />

解决方案 #2: 您可以使 RecyclerView 和 RelativeLayout 的高度与父级匹配

【讨论】:

【参考方案3】:

在 RecyclerView 上禁用嵌套滚动:

mRecyclerView.setNestedScrollingEnabled(false);

【讨论】:

以上是关于RecyclerView 一次为所有项目调用 onCreateViewHolder 和 onBindViewHolder的主要内容,如果未能解决你的问题,请参考以下文章

Joomla:一次为所有文章重新生成别名?

使用 CoreAnimation 一次为多个 UIView 设置动画

我可以一次为 Amazon S3 存储桶中的所有对象设置 expires 标头吗?

一次为多个变量分配相同的值?

是否有可能当recyclerview加载项只加载一次而不重新加载滚动?

我如何一次为每个 li 元素设置样式?