As we all know, the format of listview is certain, and the data sources are indeed diverse. At this time, an adapter is needed to convert the data sources into the format to be displayed by listview.
baseAdapter was born.
The display and caching mechanisms of listview and gridView are as follows
Everyone knows that the size of the screen is limited, but the data in the listview may be a lot, so the mobile phone can not display all the data at once, it only loads the data displayed on the screen.
As shown above, when we slide the screen down, item1 is reclaimed to recycler and item8 is displayed on the screen. item8 takes such a layout file from recycler and resets the data to be displayed by item8 and sets the location to be displayed. In short, a sentence needs to be displayed before it is reclaimed to the cache.
As for the title, what is the difference between the three realms of BaseAdapter (comic, ordinary, literary and artistic)? Just how to use the display and caching mechanism of listview
There is such a method on the adapter of listview
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- return null;
- }
Among them, the difference between the comma style and the ordinary style of literature and art lies in how to use this method.
Let's take an example to compare the three realms of adapter.
The results to be achieved are 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
- <?xml version="1.0" encoding="utf-8"?>
- <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" />
- </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<MyObject> list=new ArrayList<MyObject>();
- private ListView listView;
- private MyAdapter myAdapter;
- @Override
- protected 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<MyObject> list;
- private Context context;
- public MyAdapter(List<MyObject> list, Context context) {
- this.list = list;
- this.context = context;
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return list.size();
- }
- @Override
- public Object getItem(int position) {
- // TODO Auto-generated method stub
- return list.get(position);
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- //Comic formula
- 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", "Teasing formula" + sum);
- return view;
- //(Ordinary)
- //long star = System.nanoTime(); // Get system 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", "general"+sum);.
- // return convertView;
- //Literary and artistic style
- // 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 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 duplication of findViewById
- class ViewHolder {
- public ImageView imageView;
- private TextView nickName;
- private TextView content;
- }
- }
The code of BaseAdapter's triple realm (comma, common, literary) is already above.
Now let's analyse the first kind of funny comparison.
As mentioned earlier, liseview has a caching mechanism to put used item s into the buffer pool, and here we create new view objects every time we call the getview method without using the listview caching mechanism.
There is no treatment, efficiency and inefficiency, so we call it comma.
The second common form is to use the content view object passed in the getview method and add an if judgment.
- if (convertView == null) {
- convertView = View.inflate(context, R.layout.item, null);
- }
Although it's only an if judgment, it saves a lot of time by avoiding creating a large number of contentview objects. It takes advantage of the caching feature of ListView to create a new view without caching, which optimizes the getview method very well, but it's only an entry point, because findViewById still wastes a lot of time, so we call this method "FindViewById". Ordinary style
Then the third realm literary and artistic form is to optimize findViewById and put findViewById into if judgment statement.
We need to create an internal class with three member variables that are the three controls in our item.xml file.
- class ViewHolder {
- public ImageView imageView;
- private TextView nickName;
- private TextView content;
- }
Connect viewHolder with contentView by viewHolder.setTag() method and get viewHolder by getTag method
This method not only utilizes the cache of listview, but also realizes the cache of display view through viewHolder, avoiding using findViewById method many times.
As a sentimental programmer, this is the most literary way to write.~
You may see the log log output from my code below. I attach the results. Compare the list view here, only 50 pieces of data are all slipped to the bottom.
So far, the three realms of BaseAdapter (comic, ordinary, literary) are clear at a glance. (If there are any discrepancies, please set more data in the list view.)