天天看點

ListView的ViewHolder優化

優化後listView的資料擴充卡

以下是對Adapter經過優化之後的BaseAdapter,不管是ListView還是GridView或者其他具有清單特性的控件,在設定資料擴充卡的時候可以直接繼承

public abstract class LvBaseAdapter<T> extends BaseAdapter {
	private ArrayList<T> mDatas;

	/** 首頁listview的資料擴充卡 **/
	public LvBaseAdapter(ArrayList<T> datas) {
		mDatas = datas;
	}

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

	@Override
	public T getItem(int position) {
		return mDatas.get(position);
	}

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		Object holder = null;
		if (convertView == null) {
			convertView = View.inflate(parent.getContext(), getViewResId(position), null);
			holder = createHolderAndFindView(position, convertView);
			convertView.setTag(holder);
		} else {
			holder = convertView.getTag();
		}
		showData(position, holder, getItem(position));
		setRootViewAnimation(convertView);
		return convertView;
	}

	private void setRootViewAnimation(View convertView) {
        convertView.setScaleX(0.3f);
        convertView.setScaleY(0.3f);
        //使用NineOldAndoird實心屬性動畫
        ViewPropertyAnimator.animate(convertView)
                .scaleX(1f)
                .scaleY(1f)
                .setInterpolator(new OvershootInterpolator())
                .setDuration(500)
                .start();
    }
	
	/** 傳回擴充卡中的源資料集合 **/
	public ArrayList<T> getData() {
		return mDatas;
	}

	/**
	 * 傳回listview條目布局的資源id
	 * 
	 * @param position listview中目前條目的位置
	 **/
	public abstract int getViewResId(int position);

	/**
	 * 建立ViewHolder并且初始化布局中的控件
	 * 
	 * @param position listview中目前條目的位置
	 * @param convertView view的緩沖容器
	 **/
	public abstract Object createHolderAndFindView(int position, View convertView);

	/** 展示listview中對應條目的資料 **/
	public abstract void showData(int position, Object holder, T item);
}
           

以下是一個簡單的示例,通過繼承該BaseAdapter可以簡化邏輯(雖然代碼多了點)

public class DiscussLvAdapter extends LvBaseAdapter<Bean> {

    private List<Bean> listData;
    private View.OnTouchListener mListener;

    public DiscussLvAdapter(List<Bean> data) {
        super(data);
        listData = data;
    }

    public List<Bean> getListData() {
        return listData;
    }

    public Tweet getBeanData(int position) {
        return listData.get(position);
    }

    @Override
    public LvBaseHolder getHolder(Context context) {
        return new MyDiscussHolder(context);
    }

    private class MyDiscussHolder extends LvBaseHolder<Bean> implements View.OnClickListener {
        
        protected MyDiscussHolder(Context context) {
            super(context);
           // 做一些初始化
        }

        @Override
        public View initView(Context context) {
            View view = View.inflate(context, R.layout.item_discuss_list, null);
            initItemView(view);
            initItemListener();
            return view;
        }

        private void initItemView(View view) {
            // TODO 做初始化控件的操作
        }

        private void initItemListener() {
            // TODO 設定事件監聽器
        }

        @Override
        public void refreshData(Tweet data, int position) {
            // TODO 初始化控件的資料
        }
		
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.***:
                    // TODO 做具體條目的點選事件
                    break;
                default:
                    break;
            }
        }
    }
}
           

以下是對平常所建立的ViewHolder的抽取優化,适用于大量使用ListView展示資料的應用

public abstract class LvBaseHolder<T> {
    private View mLvItemView;
    private T data;

    protected LvBaseHolder(Context context) {
        mLvItemView = initView(context);
        mLvItemView.setTag(this);
    }

    /** 傳回listview一個條目的布局 **/
    public View getView() {
        return mLvItemView;
    }

    /** 設定listview一個條目的資料 **/
    public void setData(T data, int position) {
        this.data = data;
        refreshData(data, position);
    }

    /** 傳回listview一個條目的資料 **/
    public T getData() {
        return data;
    }

    /** 初始化listview的一個條目布局 **/
    public abstract View initView(Context context);

    /** 給listview的一個條目填充資料 **/
    public abstract void refreshData(T data, int position);
}
           

至此,對ListView的BaseAdapter和BaseHolder優化可以告一段落了,水準有限  難免有疏忽,請讀者批評指正。

另附:

Github首頁:https://github.com/zhaodecang/ 

部落格園首頁:http://www.cnblogs.com/cangsir/