• 关于RecyclerView中Viewholder和View的缓存机制的探究


    这个题目放在草稿箱里面许久了,一直没有动力提笔。趁现在公司人还没有来齐,工作量还不是很大,就挤出来时间来把它完善了。

    我们知道,RecyclerView是经典的ListView的进化与升华,它比ListView更加灵活,但也因此引入了一定的复杂性。最新的v7支持包新添加了RecyclerView。

    我们知道,ListView通过使用ViewHolder来提升性能。ViewHolder通过保存item中使用到的控件的引用来减少findViewById的调用,以此使ListView滑动得更加顺畅。但这种模式即使不使用也无妨。

    对于还不是很熟悉RecyclerView的程序员,可以先从这两篇文章里面了解一下它的基本用法:

    Android L新控件RecyclerView简介

    RecyclerView和CardView简介

    这里对RecyclerView的基本使用方式,就不再赘述,只讨论RecyclerView中的ViewHolder的缓存机制。其实它的缓存机制大致原理跟ListView是相似的,只是在具体的实现细节上面有些差异。对于这些RecyclerView的缓存机制,Android L新控件RecyclerView简介这篇文章的结尾进行了总结性的概括,这里讨论的内容要远比这篇简介的内容要复杂和多。

    首先,我定义了三个不同的Adapter,里面分别对应了三种情况:item类型只有一种;item类型有两种;item类型有三种。里面均重写了onCreateViewHolder方法,用于记录生成的ViewHolder或者View的数目。内容可以从Log里面查询得到。三个Adapter的细节分别是:

      1 /**   
      2  * @Title: MyRVAdapter.java 
      3  * @Package com.example.recyclerviewtest.adapter 
      4  * @Description: TODO
      5  * @author SilentKnight || happychinapc[at]gmail[dot]com   
      6  * @date 2015 2015年1月22日 下午4:54:25 
      7  * @version V1.0.0   
      8  */
      9 package com.example.recyclerviewtest.adapter;
     10 
     11 import java.util.List;
     12 
     13 import android.content.Context;
     14 import android.support.v7.widget.RecyclerView;
     15 import android.util.Log;
     16 import android.view.LayoutInflater;
     17 import android.view.View;
     18 import android.view.ViewGroup;
     19 import android.view.View.OnClickListener;
     20 import android.widget.TextView;
     21 import android.widget.Toast;
     22 
     23 import com.example.recyclerviewtest.R;
     24 
     25 /**
     26  * @ClassName: MyRVAdapter
     27  * @Description: TODO
     28  * @author SilentKnight || happychinapc@gmail.com
     29  * @date 2015年1月22日 下午4:54:25
     30  * 
     31  */
     32 public class MyRVAdapter extends RecyclerView.Adapter<MyRVAdapter.ViewHolder> {
     33     private static int COUNT_CACHE_VIEW = 0;
     34     private static final String ADAPTER_TAG = MyRVAdapter.class.getSimpleName();
     35     private List<String> dataSet;
     36     private Context context;
     37 
     38     public MyRVAdapter(Context context, List<String> dataSet) {
     39         this.context = context;
     40         this.dataSet = dataSet;
     41     }
     42 
     43     /*
     44      * (non-avadoc) <p>Title: getItemId</p> <p>Description: </p>
     45      * 
     46      * @params @param position
     47      * 
     48      * @params @return
     49      * 
     50      * @overrided @see
     51      * android.support.v7.widget.RecyclerView.Adapter#getItemId(int)
     52      */
     53     @Override
     54     public long getItemId(int position) {
     55         // TODO Auto-generated method stub
     56         return position;
     57     }
     58 
     59     /*
     60      * (non-avadoc) <p>Title: getItemCount</p> <p>Description: </p>
     61      * 
     62      * @params @return
     63      * 
     64      * @overrided @see
     65      * android.support.v7.widget.RecyclerView.Adapter#getItemCount()
     66      */
     67     @Override
     68     public int getItemCount() {
     69         // TODO Auto-generated method stub
     70         return dataSet.size();
     71     }
     72 
     73     /*
     74      * (non-avadoc) <p>Title: onBindViewHolder</p> <p>Description: </p>
     75      * 
     76      * @params @param arg0
     77      * 
     78      * @params @param arg1
     79      * 
     80      * @overrided @see
     81      * android.support.v7.widget.RecyclerView.Adapter#onBindViewHolder
     82      * (android.support.v7.widget.RecyclerView.ViewHolder, int)
     83      */
     84     @Override
     85     public void onBindViewHolder(ViewHolder holder, final int arg1) {
     86         // TODO Auto-generated method stub
     87         holder.tv.setOnClickListener(new OnClickListener() {
     88 
     89             @Override
     90             public void onClick(View v) {
     91                 // TODO Auto-generated method stub
     92                 Toast.makeText(context, "You clickd TextView at index of "+arg1,
     93                         Toast.LENGTH_SHORT).show();
     94             }
     95         });
     96         holder.tv.setText(dataSet.get(arg1));
     97     }
     98 
     99     /*
    100      * (non-avadoc) <p>Title: onCreateViewHolder</p> <p>Description: </p>
    101      * 
    102      * @params @param arg0
    103      * 
    104      * @params @param arg1
    105      * 
    106      * @params @return
    107      * 
    108      * @overrided @see
    109      * android.support.v7.widget.RecyclerView.Adapter#onCreateViewHolder
    110      * (android.view.ViewGroup, int)
    111      */
    112 
    113     @Override
    114     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) {
    115         // TODO Auto-generated method stub
    116         Log.i(ADAPTER_TAG, "itemTV---" + ++COUNT_CACHE_VIEW);
    117         View itemLayout = LayoutInflater.from(viewGroup.getContext()).inflate(
    118                 R.layout.recycler_view_item_layout_tv, null);
    119         return new ViewHolder(itemLayout);
    120     }
    121 
    122     public static class ViewHolder extends RecyclerView.ViewHolder {
    123         public TextView tv;
    124 
    125         /**
    126          * <p>
    127          * Title: MainActivity.java
    128          * </p>
    129          * <p>
    130          * Description:
    131          * </p>
    132          * 
    133          * @param @param itemView
    134          */
    135         public ViewHolder(View itemView) {
    136             super(itemView);
    137             // TODO Auto-generated constructor stub
    138             tv = (TextView) itemView.findViewById(R.id.rv_item_tv);
    139         }
    140     }
    141 }
    MyRVAdapter
      1 /**   
      2  * @Title: MyRVAdapter2.java 
      3  * @Package com.example.recyclerviewtest.adapter 
      4  * @Description: TODO
      5  * @author SilentKnight || happychinapc[at]gmail[dot]com   
      6  * @date 2015 2015年1月22日 下午4:55:31 
      7  * @version V1.0.0   
      8  */
      9 package com.example.recyclerviewtest.adapter;
     10 
     11 import java.util.List;
     12 
     13 import android.content.Context;
     14 import android.content.Intent;
     15 import android.support.v7.widget.RecyclerView;
     16 import android.util.Log;
     17 import android.view.LayoutInflater;
     18 import android.view.View;
     19 import android.view.ViewGroup;
     20 import android.view.View.OnClickListener;
     21 import android.widget.ImageView;
     22 import android.widget.TextView;
     23 import android.widget.Toast;
     24 
     25 import com.example.recyclerviewtest.GridViewHorizontalTest;
     26 import com.example.recyclerviewtest.GridViewVerticalTest;
     27 import com.example.recyclerviewtest.R;
     28 
     29 /**
     30  * @ClassName: MyRVAdapter2
     31  * @Description: TODO
     32  * @author SilentKnight || happychinapc@gmail.com
     33  * @date 2015年1月22日 下午4:55:31
     34  * 
     35  */
     36 public class MyRVAdapter2 extends RecyclerView.Adapter<MyRVAdapter2.ViewHolder> {
     37     private static int COUNT_CACHE_VIEW_1 = 0;
     38     private static int COUNT_CACHE_VIEW_2 = 0;
     39     private static final String ADAPTER_TAG = MyRVAdapter2.class
     40             .getSimpleName();
     41     private static final int TYPE_TV = 0x000;
     42     private static final int TYPE_IV = 0x0001;
     43     private List<String> dataSet;
     44     private Context context;
     45 
     46     public MyRVAdapter2(Context context, List<String> dataSet) {
     47         this.context = context;
     48         this.dataSet = dataSet;
     49     }
     50 
     51     /*
     52      * (non-avadoc) <p>Title: getItemId</p> <p>Description: </p>
     53      * 
     54      * @params @param position
     55      * 
     56      * @params @return
     57      * 
     58      * @overrided @see
     59      * android.support.v7.widget.RecyclerView.Adapter#getItemId(int)
     60      */
     61     @Override
     62     public long getItemId(int position) {
     63         // TODO Auto-generated method stub
     64         return position;
     65     }
     66 
     67     /*
     68      * (non-avadoc) <p>Title: getItemViewType</p> <p>Description: </p>
     69      * 
     70      * @params @param position
     71      * 
     72      * @params @return
     73      * 
     74      * @overrided @see
     75      * android.support.v7.widget.RecyclerView.Adapter#getItemViewType(int)
     76      */
     77     @Override
     78     public int getItemViewType(int position) {
     79         // TODO Auto-generated method stub
     80         if (position % 2 == 0) {
     81             return TYPE_TV;
     82         } else {
     83             return TYPE_IV;
     84         }
     85     }
     86 
     87     /*
     88      * (non-avadoc) <p>Title: getItemCount</p> <p>Description: </p>
     89      * 
     90      * @params @return
     91      * 
     92      * @overrided @see
     93      * android.support.v7.widget.RecyclerView.Adapter#getItemCount()
     94      */
     95     @Override
     96     public int getItemCount() {
     97         // TODO Auto-generated method stub
     98         return dataSet.size();
     99     }
    100 
    101     /*
    102      * (non-avadoc) <p>Title: onBindViewHolder</p> <p>Description: </p>
    103      * 
    104      * @params @param arg0
    105      * 
    106      * @params @param arg1
    107      * 
    108      * @overrided @see
    109      * android.support.v7.widget.RecyclerView.Adapter#onBindViewHolder
    110      * (android.support.v7.widget.RecyclerView.ViewHolder, int)
    111      */
    112     @Override
    113     public void onBindViewHolder(ViewHolder holder, int arg1) {
    114         // TODO Auto-generated method stub
    115         if (getItemViewType(arg1) == TYPE_TV) {
    116             holder.tv.setOnClickListener(new OnClickListener() {
    117 
    118                 @Override
    119                 public void onClick(View v) {
    120                     // TODO Auto-generated method stub
    121                     context.startActivity(new Intent(context,
    122                             GridViewHorizontalTest.class));
    123                 }
    124             });
    125             holder.tv.setText(dataSet.get(arg1));
    126         } else {
    127             holder.iv.setOnClickListener(new OnClickListener() {
    128 
    129                 @Override
    130                 public void onClick(View v) {
    131                     // TODO Auto-generated method stub
    132                     context.startActivity(new Intent(context,
    133                             GridViewVerticalTest.class));
    134                 }
    135             });
    136         }
    137     }
    138 
    139     /*
    140      * (non-avadoc) <p>Title: onCreateViewHolder</p> <p>Description: </p>
    141      * 
    142      * @params @param arg0
    143      * 
    144      * @params @param arg1
    145      * 
    146      * @params @return
    147      * 
    148      * @overrided @see
    149      * android.support.v7.widget.RecyclerView.Adapter#onCreateViewHolder
    150      * (android.view.ViewGroup, int)
    151      */
    152 
    153     @Override
    154     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) {
    155         // TODO Auto-generated method stub
    156         if (getItemViewType(arg1) == TYPE_TV) {
    157             Log.i(ADAPTER_TAG, "itemTV---" + ++COUNT_CACHE_VIEW_1);
    158             View itemLayout = LayoutInflater.from(viewGroup.getContext())
    159                     .inflate(R.layout.recycler_view_item_layout_tv, null);
    160             return new ViewHolder(itemLayout, TYPE_TV);
    161         } else {
    162             Log.i(ADAPTER_TAG, "itemIV---" + ++COUNT_CACHE_VIEW_2);
    163             View itemLayout = LayoutInflater.from(viewGroup.getContext())
    164                     .inflate(R.layout.recycler_view_item_layout_iv, null);
    165             return new ViewHolder(itemLayout, TYPE_IV);
    166         }
    167     }
    168 
    169     public static class ViewHolder extends RecyclerView.ViewHolder {
    170         public TextView tv;
    171         public ImageView iv;
    172 
    173         /**
    174          * <p>
    175          * Title: MainActivity.java
    176          * </p>
    177          * <p>
    178          * Description:
    179          * </p>
    180          * 
    181          * @param @param itemView
    182          */
    183         public ViewHolder(View itemView, int itemType) {
    184             super(itemView);
    185             // TODO Auto-generated constructor stub
    186             if (itemType == TYPE_TV) {
    187                 tv = (TextView) itemView.findViewById(R.id.rv_item_tv);
    188             } else {
    189                 iv = (ImageView) itemView.findViewById(R.id.rv_item_iv);
    190             }
    191         }
    192     }
    193 }
    MyRVAdapter2
      1 /**   
      2  * @Title: MyRVAdapter3.java 
      3  * @Package com.example.recyclerviewtest.adapter 
      4  * @Description: TODO
      5  * @author SilentKnight || happychinapc[at]gmail[dot]com   
      6  * @date 2015 2015年1月22日 下午4:56:33 
      7  * @version V1.0.0   
      8  */
      9 package com.example.recyclerviewtest.adapter;
     10 
     11 import java.util.List;
     12 
     13 import android.content.Context;
     14 import android.support.v7.widget.RecyclerView;
     15 import android.util.Log;
     16 import android.view.LayoutInflater;
     17 import android.view.View;
     18 import android.view.ViewGroup;
     19 import android.view.View.OnClickListener;
     20 import android.widget.ImageView;
     21 import android.widget.TextView;
     22 import android.widget.Toast;
     23 
     24 import com.example.recyclerviewtest.R;
     25 
     26 /**
     27  * @ClassName: MyRVAdapter3
     28  * @Description: TODO
     29  * @author SilentKnight || happychinapc@gmail.com
     30  * @date 2015年1月22日 下午4:56:33
     31  * 
     32  */
     33 public class MyRVAdapter3 extends RecyclerView.Adapter<MyRVAdapter3.ViewHolder> {
     34     private static int COUNT_CACHE_VIEW_1 = 0;
     35     private static int COUNT_CACHE_VIEW_2 = 0;
     36     private static int COUNT_CACHE_VIEW_3 = 0;
     37     private static final String ADAPTER_TAG = MyRVAdapter3.class
     38             .getSimpleName();
     39     private static final int TYPE_TV = 0x000;
     40     private static final int TYPE_IV = 0x0001;
     41     private static final int TYPE_TV_2 = 0x0002;
     42     private List<String> dataSet;
     43     private Context context;
     44 
     45     public MyRVAdapter3(Context context, List<String> dataSet) {
     46         this.context = context;
     47         this.dataSet = dataSet;
     48     }
     49 
     50     /*
     51      * (non-avadoc) <p>Title: getItemId</p> <p>Description: </p>
     52      * 
     53      * @params @param position
     54      * 
     55      * @params @return
     56      * 
     57      * @overrided @see
     58      * android.support.v7.widget.RecyclerView.Adapter#getItemId(int)
     59      */
     60     @Override
     61     public long getItemId(int position) {
     62         // TODO Auto-generated method stub
     63         return position;
     64     }
     65 
     66     /*
     67      * (non-avadoc) <p>Title: getItemViewType</p> <p>Description: </p>
     68      * 
     69      * @params @param position
     70      * 
     71      * @params @return
     72      * 
     73      * @overrided @see
     74      * android.support.v7.widget.RecyclerView.Adapter#getItemViewType(int)
     75      */
     76     @Override
     77     public int getItemViewType(int position) {
     78         // TODO Auto-generated method stub
     79         if (position % 3 == 0) {
     80             return TYPE_TV;
     81         } else if (position % 3 == 1) {
     82             return TYPE_IV;
     83         } else {
     84             return TYPE_TV_2;
     85         }
     86     }
     87 
     88     /*
     89      * (non-avadoc) <p>Title: getItemCount</p> <p>Description: </p>
     90      * 
     91      * @params @return
     92      * 
     93      * @overrided @see
     94      * android.support.v7.widget.RecyclerView.Adapter#getItemCount()
     95      */
     96     @Override
     97     public int getItemCount() {
     98         // TODO Auto-generated method stub
     99         return dataSet.size();
    100     }
    101 
    102     /*
    103      * (non-avadoc) <p>Title: onBindViewHolder</p> <p>Description: </p>
    104      * 
    105      * @params @param arg0
    106      * 
    107      * @params @param arg1
    108      * 
    109      * @overrided @see
    110      * android.support.v7.widget.RecyclerView.Adapter#onBindViewHolder
    111      * (android.support.v7.widget.RecyclerView.ViewHolder, int)
    112      */
    113     @Override
    114     public void onBindViewHolder(ViewHolder holder, int arg1) {
    115         // TODO Auto-generated method stub
    116         if (getItemViewType(arg1) == TYPE_TV) {
    117             holder.tv.setOnClickListener(new OnClickListener() {
    118 
    119                 @Override
    120                 public void onClick(View v) {
    121                     // TODO Auto-generated method stub
    122                     Toast.makeText(context, "You clickd TextView",
    123                             Toast.LENGTH_SHORT).show();
    124                 }
    125             });
    126             holder.tv.setText(dataSet.get(arg1));
    127         } else if (getItemViewType(arg1) == TYPE_IV) {
    128             holder.iv.setOnClickListener(new OnClickListener() {
    129 
    130                 @Override
    131                 public void onClick(View v) {
    132                     // TODO Auto-generated method stub
    133 
    134                     Toast.makeText(context, "You clickd ImageView",
    135                             Toast.LENGTH_SHORT).show();
    136                 }
    137             });
    138         } else {
    139 
    140         }
    141     }
    142 
    143     /*
    144      * (non-avadoc) <p>Title: onCreateViewHolder</p> <p>Description: </p>
    145      * 
    146      * @params @param arg0
    147      * 
    148      * @params @param arg1
    149      * 
    150      * @params @return
    151      * 
    152      * @overrided @see
    153      * android.support.v7.widget.RecyclerView.Adapter#onCreateViewHolder
    154      * (android.view.ViewGroup, int)
    155      */
    156 
    157     @Override
    158     public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) {
    159         // TODO Auto-generated method stub
    160         if (getItemViewType(arg1) == TYPE_TV) {
    161             Log.i(ADAPTER_TAG, "itemTV---" + ++COUNT_CACHE_VIEW_1);
    162             View itemLayout = LayoutInflater.from(viewGroup.getContext())
    163                     .inflate(R.layout.recycler_view_item_layout_tv, null);
    164             return new ViewHolder(itemLayout, TYPE_TV);
    165         } else if (getItemViewType(arg1) == TYPE_IV) {
    166             Log.i(ADAPTER_TAG, "itemIV---" + ++COUNT_CACHE_VIEW_2);
    167             View itemLayout = LayoutInflater.from(viewGroup.getContext())
    168                     .inflate(R.layout.recycler_view_item_layout_iv, null);
    169             return new ViewHolder(itemLayout, TYPE_IV);
    170         } else {
    171             Log.i(ADAPTER_TAG, "itemTV2---" + ++COUNT_CACHE_VIEW_3);
    172             View itemLayout = LayoutInflater.from(viewGroup.getContext())
    173                     .inflate(R.layout.recycler_view_item_layout_tv_2, null);
    174             return new ViewHolder(itemLayout, TYPE_TV_2);
    175         }
    176     }
    177 
    178     public static class ViewHolder extends RecyclerView.ViewHolder {
    179         public TextView tv;
    180         public TextView tv2;
    181         public ImageView iv;
    182 
    183         /**
    184          * <p>
    185          * Title: MainActivity.java
    186          * </p>
    187          * <p>
    188          * Description:
    189          * </p>
    190          * 
    191          * @param @param itemView
    192          */
    193         public ViewHolder(View itemView, int itemType) {
    194             super(itemView);
    195             // TODO Auto-generated constructor stub
    196             if (itemType == TYPE_TV) {
    197                 tv = (TextView) itemView.findViewById(R.id.rv_item_tv);
    198             } else if (itemType == TYPE_IV) {
    199                 iv = (ImageView) itemView.findViewById(R.id.rv_item_iv);
    200             } else {
    201                 tv2 = (TextView) itemView.findViewById(R.id.rv_item_tv);
    202             }
    203         }
    204     }
    205 }
    MyRVAdapter3

    同时,这个测试工程里面只有一个Activity,它的详情如下:

     1 package com.example.recyclerviewtest;
     2 
     3 import java.util.List;
     4 
     5 import com.example.recyclerviewtest.adapter.MyRVAdapter;
     6 import com.example.recyclerviewtest.adapter.MyRVAdapter2;
     7 import com.example.recyclerviewtest.adapter.MyRVAdapter3;
     8 import com.example.recyclerviewtest.util.Utils;
     9 
    10 import android.support.v7.app.ActionBarActivity;
    11 import android.support.v7.widget.LinearLayoutManager;
    12 import android.support.v7.widget.RecyclerView;
    13 import android.os.Bundle;
    14 import android.widget.LinearLayout;
    15 
    16 public class MainActivity extends ActionBarActivity {
    17     private static final String TAG = MainActivity.class.getSimpleName();
    18 
    19     private RecyclerView rvHorizontal;
    20     private RecyclerView rvVertical;
    21 
    22     @Override
    23     protected void onCreate(Bundle savedInstanceState) {
    24         super.onCreate(savedInstanceState);
    25         setContentView(R.layout.activity_main);
    26         rvHorizontal = (RecyclerView) findViewById(R.id.recyclier_view_horizontal);
    27         rvVertical = (RecyclerView) findViewById(R.id.recyclier_view_vertical);
    28         List<String> dataSet = Utils.generateDataSet();
    29         LinearLayoutManager layoutManager = new LinearLayoutManager(this,
    30                 LinearLayout.HORIZONTAL, false);
    31         rvHorizontal.setLayoutManager(layoutManager);
    32         layoutManager = new LinearLayoutManager(this, LinearLayout.VERTICAL,
    33                 false);
    34         rvVertical.setLayoutManager(layoutManager);
    35         MyRVAdapter adapter = new MyRVAdapter(this, dataSet);
    36         MyRVAdapter2 adapter2 = new MyRVAdapter2(this, dataSet);
    37         MyRVAdapter3 adapter3 = new MyRVAdapter3(this, dataSet);
    38         rvHorizontal.setAdapter(adapter2);
    39         rvVertical.setAdapter(adapter);
    40     }
    41 
    42 }
    MainActivity

    对于你想测试的三种情况,你可以通达代码rvHorizontal.setAdapter(adapter2)和rvVertical.setAdapter(adapter)来进行测试。在测试的过程中,可以通过改变RecyclerView的宽度来测试显示ViewHolder的数目。比如,item的宽度为60dp,你可以分别测试下RecyclerView的宽度分别为60dp、120dp和180dp情况下log的打印情况。其中,activity的布局文件如下:

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:paddingBottom="@dimen/activity_vertical_margin"
     6     android:paddingLeft="@dimen/activity_horizontal_margin"
     7     android:paddingRight="@dimen/activity_horizontal_margin"
     8     android:paddingTop="@dimen/activity_vertical_margin"
     9     tools:context="com.example.recyclerviewtest.MainActivity" >
    10 
    11     <android.support.v7.widget.RecyclerView
    12         android:id="@+id/recyclier_view_horizontal"
    13         android:layout_width="240dp"
    14         android:layout_height="70dp"
    15         android:layout_alignParentTop="true"
    16         android:layout_centerHorizontal="true"
    17         android:scrollbars="horizontal" >
    18     </android.support.v7.widget.RecyclerView>
    19 
    20     <android.support.v7.widget.RecyclerView
    21         android:id="@+id/recyclier_view_vertical"
    22         android:layout_width="match_parent"
    23         android:layout_height="360dp"
    24         android:layout_below="@id/recyclier_view_horizontal"
    25         android:layout_centerHorizontal="true"
    26         android:scrollbars="vertical" >
    27     </android.support.v7.widget.RecyclerView>
    28 
    29 </RelativeLayout>
    activity_main.xml

    其中一个item的布局如下:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:gravity="center"
     6     android:orientation="vertical" >
     7 
     8     <TextView
     9         android:id="@+id/rv_item_tv"
    10         android:layout_width="60dp"
    11         android:layout_height="20dp"
    12         android:layout_gravity="center"
    13         android:background="@drawable/item_selector"
    14         android:clickable="true"
    15         android:focusable="true"
    16         android:focusableInTouchMode="true"
    17         android:gravity="center" >
    18     </TextView>
    19 
    20 </LinearLayout>
    recycler_view_item_layout_tv.xml

    总之,测试的结论是这样的:在只有一种item的情况下,缓存的ViewHolder的数目为RecyclerView在滑动过程中所能在一屏内容纳的最大item个数+2。比如,在一个屏幕中只有item A可以显示,在滑动的过程最多可以出现6个item(这个最多是指所有item的个数,包括显示完全和显示不完全的总数),那么ViewHolder的缓存个数将会是8;而有至少两种item显示的情况下,每种item的ViewHolder的缓存个数为单种item在一屏内最大显示个数+1;比如,有3种item A,B,C,在滑动的过程,item A最多的情况下一屏显示了2个,那个item A对应的ViewHolder的缓存个数就是3个。

    工程源文件可以从下面的链接打开下载。

    点击下载源码

  • 相关阅读:
    SharedPreferences
    短信发送器的实现
    第四周总结
    本周开发工作时间及内容
    自我总结
    随笔
    结对编程
    目前流行的源程序版本管理软件和项目管理软件都有哪些, 各有什么优缺点?
    八皇后
    数制转换
  • 原文地址:https://www.cnblogs.com/littlepanpc/p/4241575.html
Copyright © 2020-2023  润新知