Android: The ListView cache mechanism and the three realms of BaseAdapter (simple, simple, and artistic)
As we all know, the listview format is certain, and the data source is indeed multiple and diverse. At this time, an adapter is required to convert the data source to the format to be displayed by listview.
BaseAdapter is born.
The display and cache mechanisms of listview and gridView are as follows:
As we all know, the screen size is limited, but there may be a lot of data in the listview, so the mobile phone cannot display all the data at once. It only loads the data displayed on the screen.
For example, when we slide down the screen, item1 will be recycled to recycler, and item8 will be displayed on the screen. item8 will retrieve such a layout file from recycler, reset the data to be displayed in item8, and set location. In a word, after the display is complete, it is recycled to the cache.
As for the question, why is the difference between the three realms of BaseAdapter (funny, common, and literary? How to Use the display and cache mechanism of listview
There is such a method on the listview Adapter
@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubreturn null;}
The difference between funny and ordinary Literary Styles lies in how to use this method.
Next we will use an instance to compare the weak or strong status of the adapter.
The effect is as follows:
Activity_main.xml
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <listview android:id="@+id/lv_listView" android:layout_width="match_parent" android:layout_height="match_parent"></listview></linearlayout>
Item. xml
<! -- {Cke_protected} {C} % 3C! % 2D % 2D % 3 Fxml % 20 version % 3D % 221.0% 20 encoding % 3D % 22utf-8% 22% 3F % 2D % 2D % 3E --> <relativelayout xmlns: android = "http://schemas.android.com/apk/res/android" android: layout_width = "match_parent" android: layout_height = "match_parent"> <imageview android: id = "@ + id/iv_image" android: layout_width = "50dp" android: layout_height = "50dp" android: layout_alignparentleft = "true" android: src = "@ drawable/ic_launcher"> <textview android: id = "@ + id/TV _nickName" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: layout_torightof = "@ id/iv_image" android: gravity = "center_horizontal" android: textsize = "20sp" android: text = "nickname"> <textview android: id = "@ + id/TV _content" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: layout_torightof = "@ id/iv_image" android: layout_below = "@ id/TV _nickName" android: textsize = "15sp" android: text = "content"> </textview> </imageview> </relativelayout>
For convenience, I created a myObject object to encapsulate the data to be displayed in item. xml.
MyObject. class
package com.example.baseadapter;import android.widget.ImageView;import android.widget.TextView;public class MyObject {private int imageViewId;private String nickName;private String content;public MyObject(int imageViewId, String nickName, String content) {this.imageViewId = imageViewId;this.nickName = nickName;this.content = content;}public String getNickName() {return nickName;}public String getContent() {return content;}public int getImageViewId() {return imageViewId;}}
MainActivity. class
Package com. example. baseadapter; import java. util. arrayList; import java. util. list; import android. OS. bundle; import android. app. activity; import android. view. menu; import android. widget. listView; public class MainActivity extends Activity {private List
List = new ArrayList
(); Private ListView listView; private MyAdapter myAdapter; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); listView = (ListView) findViewById (R. id. lv_listView); for (int I = 0; I <50; I ++) {list. add (new MyObject (R. drawable. ic_launcher, "nickname" + I, "content" + I);} myAdapter = new MyAdapter (list, this); listView. setAdapter (myAdapter );}}
Custom adapter
MyAdapter. class
Package com. example. baseadapter; import java. util. list; import android. content. context; import android. util. log; import android. view. view; import android. view. viewGroup; import android. widget. baseAdapter; import android. widget. imageView; import android. widget. textView; public class MyAdapter extends BaseAdapter {private long sum = 0; private List
List; private Context context; public MyAdapter (List
List, Context context) {this. list = list; this. context = context;} @ Overridepublic int getCount () {// TODO Auto-generated method stubreturn list. size () ;}@ Overridepublic Object getItem (int position) {// TODO Auto-generated method stubreturn list. get (position) ;}@ Overridepublic long getItemId (int position) {// TODO Auto-generated method stubreturn position ;}@ Overridepublic View getView (int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stub // tease ratio long star = System. nanoTime (); View view = View. inflate (context, R. layout. item, null); ImageView imageView = (ImageView) view. findViewById (R. id. iv_image); TextView nickName = (TextView) view. findViewById (R. id. TV _nickName); TextView content = (TextView) view. findViewById (R. id. TV _content); MyObject myObject = list. get (position); imageView. setBackgroundResource (myObject. getImageViewId (); nickName. setText (myObject. getNickName (); content. setText (myObject. getContent (); long end = System. nanoTime (); sum + = end-star; Log. d ("main", "Funny ratio" + sum); return view; // common // long star = System. nanoTime (); // obtain the system's nanosecond time // if (convertView = null) {// convertView = View. inflate (context, R. layout. item, null); // ImageView imageView = (ImageView) convertView //. findViewById (R. id. iv_image); // TextView nickName = (TextView) convertView //. findViewById (R. id. TV _nickName); // TextView content = (TextView) convertView. findViewById (R. id. TV _content); // MyObject myObject = list. get (position); // imageView. setBackgroundResource (myObject. getImageViewId (); // nickName. setText (myObject. getNickName (); // content. setText (myObject. getContent (); // long end = System. nanoTime (); // sum + = end-star; // Log. d ("main", "common" + sum); // return convertView; // literary // long star = System. nanoTime (); // ViewHolder viewHolder; // if (convertView = null) {// viewHolder = new ViewHolder (); // convertView = View. inflate (context, R. layout. item, null); // viewHolder. imageView = (ImageView) convertView //. findViewById (R. id. iv_image); // viewHolder. nickName = (TextView) convertView //. findViewById (R. id. TV _nickName); // viewHolder. content = (TextView) convertView //. findViewById (R. id. TV _content); // bind viewHolder and convertView together by using setTag. // convertView. setTag (viewHolder); // viewHolder = (ViewHolder) convertView. getTag (); // MyObject myObject = list. get (position); // viewHolder. imageView. setBackgroundResource (myObject. getImageViewId (); // viewHolder. nickName. setText (myObject. getNickName (); // viewHolder. content. setText (myObject. getContent (); // long end = System. nanoTime (); // sum + = end-star; // Log. d ("main", "Literary Style" + sum); // return convertView;} // avoid repeated findViewByIdclass ViewHolder {public ImageView imageView; private TextView nickName; private TextView content ;}}
The codes of BaseAdapter's Triple Realm (funny, normal, and literary) are already on the top
Next, let's analyze why the first one is called Funny comparison.
As mentioned above, liseview has a caching mechanism to put used items into the buffer pool, every time we call the getview method, we create a new view object and do not use the listview cache mechanism.
There is no processing, efficiency, and inefficiency, so we call it a funny comparison.
The second common method is to use the contentview object passed in the getview method and add an if judgment.
if (convertView == null) {convertView = View.inflate(context, R.layout.item, null);}
Although it is only an if judgment, this judgment can avoid creating a large number of contentview objects, saving a lot of time using the cache feature of ListView. if there is no cache, a new view is created, and the getview method is very good optimization, but this is just an entry, because findViewById still wastes a lot of time, we call this method a normal method.
The third method is to optimize findViewById and put findViewById into the if judgment statement.
We need to create an internal class with three member variables which are three controls in our item. xml file.
class ViewHolder {public ImageView imageView;private TextView nickName;private TextView content;}
Use the viewHolder. setTag () method to associate viewHolder with contentView, and then use the getTag method to obtain viewHolder.
This method not only uses the listview cache, but also uses viewHolder to cache the display view, avoiding the use of the findViewById method multiple times.
As a sentimental programmer, this is the most literary style ~
You may see the log output in my code. below is the attached result. You can compare that only 50 pieces of data in listview are at the bottom of the slide.
At this point, the three realms of BaseAdapter (simple, simple, and literary) are obvious ~ (If there is any discrepancy, please set more data in listview)