ListView使用多个item布局的用法及分析,Adapter的getView方法convertView的缓存的分析(附源码)

版权声明:如有侵权,请联系[email protected]。 https://blog.csdn.net/cs373616511/article/details/80429976

Different list items’layouts

Let’s move to the “more complicated” example. How about to add separator somewhere to the list.

You should do the following:

  1. Override getViewTypeCount() – return how many different view layouts you have
  2. Override getItemViewType(int) – return correct view type id by position
  3. Create correct convertView (depending on view item type) in getView

    当我们使用两个item布局的时候,getView()时用两种类型区分,使用不同的ViewHolder。本例item中的view都是TextView所以就使用一个ViewHolder。

convertView的缓存的分析:

getView方法:

 @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            int type = getItemViewType(position);
            System.out.println("getView " + position + " " + convertView + " type = " + type);
            if (convertView == null) {
                holder = new ViewHolder();
                switch (type) {
                    case TYPE_ITEM:
                        convertView = mInflater.inflate(R.layout.item1, null);
                        holder.textView = (TextView)convertView.findViewById(R.id.text);
                        break;
                    case TYPE_SEPARATOR:
                        convertView = mInflater.inflate(R.layout.item2, null);
                        holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
                        break;
                }
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder)convertView.getTag();
            }
            holder.textView.setText(mData.get(position));
            return convertView;
        }

首先启动项目:


console打印:

I/System.out: getView 0 null type = 0
I/System.out: getView 1 null type = 0
I/System.out: getView 2 null type = 0
I/System.out: getView 3 null type = 0
I/System.out: getView 4 null type = 1
I/System.out: getView 5 null type = 0
I/System.out: getView 6 null type = 0
I/System.out: getView 7 null type = 0

滑动屏幕(滑动到19再滑动到0)观察结果:

直到第十个才出现不是null的convertView

type=0缓存了8个convertView,无论如何滑动,type=0的convertView都是相同的hashCode(出现8次)

type=1缓存了2个convertView,无论如何滑动,type=1的convertView都是相同的hashCode(出现2次)

(出现8次是因为前8次都是null)

Adapter会根据type和position得到正确的convertView传参到getView方法。

I/System.out: getView 0 null type = 0
I/System.out: getView 1 null type = 0
              getView 2 null type = 0
I/System.out: getView 3 null type = 0
              getView 4 null type = 1
I/System.out: getView 5 null type = 0
I/System.out: getView 6 null type = 0
              getView 7 null type = 0
I/System.out: getView 8 null type = 0
I/System.out: getView 9 null type = 1
I/System.out: getView 10 android.widget.LinearLayout{ede7cb7 V.E...... ........ 0,-267-1080,3} type = 0
I/System.out: getView 11 android.widget.LinearLayout{b450c24 V.E...... ........ 0,-270-1080,0} type = 0
I/System.out: getView 12 android.widget.LinearLayout{df1538d V.E...... ........ 0,-267-1080,3} type = 0
I/System.out: getView 13 android.widget.LinearLayout{343b942 V.E...... ........ 0,-258-1080,12} type = 0
I/System.out: getView 14 android.widget.LinearLayout{1542d53 V.E...... ........ 0,-57-1080,0} type = 1
I/System.out: getView 15 android.widget.LinearLayout{7d8c690 V.E...... ........ 0,-247-1080,23} type = 0
I/System.out: getView 16 android.widget.LinearLayout{72c9b89 V.E...... ........ 0,-268-1080,2} type = 0
I/System.out: getView 17 android.widget.LinearLayout{a58278e V.E...... ........ 0,-270-1080,0} type = 0
I/System.out: getView 18 android.widget.LinearLayout{96a4baf V.E...... ........ 0,-268-1080,2} type = 0
I/System.out: getView 19 android.widget.LinearLayout{dabbbbc V.E...... ........ 0,-57-1080,0} type = 1
I/System.out: getView 11 android.widget.LinearLayout{b450c24 V.E...... ........ 0,-265-1080,5} type = 0
I/System.out: getView 10 android.widget.LinearLayout{ede7cb7 V.E...... ........ 0,-270-1080,0} type = 0
I/System.out: getView 9 android.widget.LinearLayout{dabbbbc V.E...... ........ 0,1683-1080,1740} type = 1
I/System.out: getView 8 android.widget.LinearLayout{a58278e V.E...... ........ 0,1703-1080,1973} type = 0
I/System.out: getView 7 android.widget.LinearLayout{72c9b89 V.E...... ........ 0,1670-1080,1940} type = 0
I/System.out: getView 6 android.widget.LinearLayout{7d8c690 V.E...... ........ 0,1620-1080,1890} type = 0
I/System.out: getView 5 android.widget.LinearLayout{343b942 V.E...... ........ 0,1701-1080,1971} type = 0
I/System.out: getView 4 android.widget.LinearLayout{1542d53 V.E...... ........ 0,1657-1080,1714} type = 1
I/System.out: getView 3 android.widget.LinearLayout{df1538d V.E...... ........ 0,1703-1080,1973} type = 0
I/System.out: getView 2 android.widget.LinearLayout{b450c24 V.E...... ........ 0,1651-1080,1921} type = 0
I/System.out: getView 1 android.widget.LinearLayout{ede7cb7 V.E...... ........ 0,1692-1080,1962} type = 0
I/System.out: getView 0 android.widget.LinearLayout{96a4baf V.E...... ........ 0,1674-1080,1944} type = 0

Activity源码:

package com.asyf.testlistview;

import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.TreeSet;

public class MultipleItemsList extends ListActivity {

    private MyCustomAdapter mAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapter = new MyCustomAdapter();
        for (int i = 1; i < 50; i++) {
            mAdapter.addItem("item " + i);
            if (i % 4 == 0) {
                mAdapter.addSeparatorItem("separator " + i);
            }
        }
        setListAdapter(mAdapter);
    }

    private class MyCustomAdapter extends BaseAdapter {

        private static final int TYPE_ITEM = 0;
        private static final int TYPE_SEPARATOR = 1;
        private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;

        private ArrayList<String> mData = new ArrayList<String>();
        private LayoutInflater mInflater;

        private TreeSet<Integer> mSeparatorsSet = new TreeSet<Integer>();

        public MyCustomAdapter() {
            mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        public void addItem(final String item) {
            mData.add(item);
            notifyDataSetChanged();
        }

        public void addSeparatorItem(final String item) {
            mData.add(item);
            // save separator position
            mSeparatorsSet.add(mData.size() - 1);
            notifyDataSetChanged();
        }

        @Override
        public int getItemViewType(int position) {
            return mSeparatorsSet.contains(position) ? TYPE_SEPARATOR : TYPE_ITEM;
        }

        @Override
        public int getViewTypeCount() {
            return TYPE_MAX_COUNT;
        }

        @Override
        public int getCount() {
            return mData.size();
        }

        @Override
        public String getItem(int position) {
            return mData.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            int type = getItemViewType(position);
            System.out.println("getView " + position + " " + convertView + " type = " + type);
            if (convertView == null) {
                holder = new ViewHolder();
                switch (type) {
                    case TYPE_ITEM:
                        convertView = mInflater.inflate(R.layout.item1, null);
                        holder.textView = (TextView)convertView.findViewById(R.id.text);
                        break;
                    case TYPE_SEPARATOR:
                        convertView = mInflater.inflate(R.layout.item2, null);
                        holder.textView = (TextView)convertView.findViewById(R.id.textSeparator);
                        break;
                }
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder)convertView.getTag();
            }
            holder.textView.setText(mData.get(position));
            return convertView;
        }

    }

    public static class ViewHolder {
        public TextView textView;
    }
}
 项目源码下载 https://gitee.com/373616511/TestListView.git

猜你喜欢

转载自blog.csdn.net/cs373616511/article/details/80429976