reclyview 复用机制_探索RecyclerView的ViewHolder复用机制

啥是RecyclerView

A flexible view for providing a limited window into a large data set.

一个在大小有限的窗口内展示大量数据集的view。恩,我的翻译一向不咋滴。。所以原文也放上了。

RecyclerView网上很多文都说是用来取代ListView和GridView的,事实上RecyclerView的确可以做到ListView和GridView能做的事,而且他将ViewHolder和Adapter都作为内部类,写在了RecyclerView中。先不管这把所有类都写在RecyclerView内部的做法是否好,但是ViewHolder作为RecyclerView内部复用的单位,直接避免了不必要的findViewById,而在ListView中则需要我们自己定义ViewHolder。

一个使用RecyclerView的示例

在进行探究之前,首先回顾一下我们是如何使用一个RecyclerView的。

第一步在布局文件里加上RecyclerView:

第二步,给RecyclerView的item编写布局:

第三步,为RecyclerView写一个Adapter:

packagecom.xiasuhuei321.test;importandroid.content.Context;importandroid.support.v7.widget.RecyclerView;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.support.v7.widget.RecyclerView.ViewHolder;/**

* Created by xiasuhuei321 on 2016/12/25.

* author:luo

* e-mail:xiasuhuei321@163.com

*/publicclassTestAdapterextendsRecyclerView.Adapter{ContextmContext;publicTestAdapter(Contextcontext){this.mContext=context;}@OverridepublicViewHolderonCreateViewHolder(ViewGroupparent,intviewType){returnnewItemViewHolder(LayoutInflater.from(mContext).inflate(R.layout.item_test,parent,false));}@OverridepublicintgetItemCount(){return100;}@OverridepublicvoidonBindViewHolder(ViewHolderholder,intposition){}classItemViewHolderextendsViewHolder{publicItemViewHolder(ViewitemView){super(itemView);}}}

这里只是简单的演示,代码写的都非常的简单。。各位都不要模仿。。。

第四步,给RecyclerView设置对应的布局和Adapter:

packagecom.xiasuhuei321.test;importandroid.os.Bundle;importandroid.support.annotation.Nullable;importandroid.support.v7.app.AppCompatActivity;importandroid.support.v7.widget.LinearLayoutManager;importandroid.support.v7.widget.RecyclerView;/**

* Created by xiasuhuei321 on 2016/12/25.

* author:luo

* e-mail:xiasuhuei321@163.com

*/publicclassTestActivityextendsAppCompatActivity{privateRecyclerViewmList;@OverrideprotectedvoidonCreate(@NullableBundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);mList=(RecyclerView)findViewById(R.id.rv_list);mList.setLayoutManager(newLinearLayoutManager(this));mList.setAdapter(newTestAdapter(this));}}

最后看下效果

7b54f6af0899

呆毛王

通过以上的流程,对RecyclerView的简单使用就过完了,在这个流程中,可以看出编写Adapter是一个关键,事实上RecyclerView和ListView都一样,都是通过Adapter来设置和管理每一个item的。

ViewHolder与复用

在复写RecyclerView.Adapter的时候,需要我们复写两个方法:

onCreateViewHolder

onBindViewHolder

这两个方法从字面上看就是创建ViewHolder和绑定ViewHolder的意思,来看一下源码中对我们实现的这两个方法的注释:

/**

* Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent

* an item.

*

* This new ViewHolder should be constructed with a new View that can represent the items

* of the given type. You can either create a new View manually or inflate it from an XML

* layout file.

*

* The new ViewHolder will be used to display items of the adapter using

* {@link #onBindViewHolder(ViewHolder, int, List)}. Since it will be re-used to display

* different items in the data set, it is a good idea to cache references to sub views of

* the View to avoid unnecessary {@link View#findViewById(int)} calls.

*

* @param parent The ViewGroup into which the new View will be added after it is bound to

*              an adapter position.

* @param viewType The view type of the new View.

*

* @return A new ViewHolder that holds a View of the given view type.

* @see #getItemViewType(int)

* @see #onBindViewHolder(ViewHolder, int)

*/

当RecyclerView需要一个新的类型的item的ViewHolder的时候调用这个方法。

第二段描述是讲如何创建这个ViewHolder,跳过。

新的ViewHolder将会被用来通过adapter调用onBindViewHolder展示item。由于它将会被复用去展示在数据集中的不同items,所以缓存View的子view引用去避免不必要的对findViewById方法的调用是一个好主意。

看了上面的这段话,我产生了一个疑问,第一段话的意思仿佛是只有在需要新的类型的ViewHolder的时候才需要调用这个方法。如果是这样,的确可以从侧面说明他是以ViewHolder为单位来实现复用的。为了验

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RecyclerViewViewHolder复用机制是其高效的一个特点,即每次滑动RecyclerView时,不会创建新的ViewHolder,而是重复利用已经创建过的ViewHolder,以避免性能问题。然而,这种复用机制可能会产生一些问题,例如在更改字体颜色时,有时可能无法生效。这是为什么呢? 其实,ViewHolder复用机制的本质是重用View而不是ViewHolder,ViewHolder只是用来保存已经创建的View,以便快速访问。当滑动RecyclerView时,如果ViewHolder已经存在,则会直接调用它的bind方法,将新的数据绑定到它的View上。如果ViewHolder不存在,则会调用其create方法来创建ViewHolder和View。这些已经被创建的View将被存储在RecyclerView的内存池中,以供下一次调用时重用。 因此,在更改字体颜色时,可能由于ViewHolder和View已经被创建过,但其颜色设置仍然保留在内存池中,这导致新的颜色设置被覆盖或无法生效。为了解决这个问题,我们可以在bind方法中显式地更改字体颜色,以确保它被正确更新。同时,我们需要确保每次ViewHolder复用时都正确地更新所有的View。这就需要我们在创建ViewHolder时,对所有的View进行初始化,确保每个View的颜色都被正确设置。 综上所述,我们需要在bind方法中显式地更改字体颜色,并在ViewHolder创建时对所有View进行正确的初始化,以确保RecyclerViewViewHolder复用机制不会导致更改字体颜色失效的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值