天天看点

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/