BaseAdapter抽取更精简的Adapter,方便复用

参考博客:http://stormzhang.github.io/androidtips/2014/08/31/android-common-simplebaseadapter/

一般我们在写ListView的时候,需要写一个BaseAdapter,要复写其4个方法,而且还有holder,相当麻烦.

通过下面的代码可以简化开发,下面的代码是参考上面的博客上的,我加了几句注释,下面我会按照自己的理解谈一谈如何抽取.

/**
 * 使用此adapter需要实现:
 * 构造函数(Context context, List<String> data)
 * getItemResource()  将item的布局文件id返回
 * getItemView(int position, View convertView, ViewHolder holder)  拿到item的某个view,并填写数据 
 * 
 * @author mio
 *
 * @param <T>
 */
public abstract class SimpleBaseAdapter<T> extends BaseAdapter {

	
    protected Context context;
    protected List<T> data;

    public SimpleBaseAdapter(Context context, List<T> data) {
        this.context = context;
        this.data = data == null ? new ArrayList<T>() : new ArrayList<T>(data);
    }

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

    @Override
    public Object getItem(int position) {
        if (position >= data.size())
            return null;
        return data.get(position);
    }

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

    /**
     * 改方法需要子类实现,需要返回item布局的resource id
     * 
     * @return
     */
    public abstract int getItemResource();

    /**
     * 使用该getItemView方法替换原来的getView方法,需要子类实现
     * 
     * @param position
     * @param convertView
     * @param holder
     * @return
     */
    public abstract View getItemView(int position, View convertView, ViewHolder holder);

    
    @SuppressWarnings("unchecked")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (null == convertView) {
            convertView = View.inflate(context, getItemResource(), null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        return getItemView(position, convertView, holder);
    }

    public class ViewHolder {
        private SparseArray<View> views = new SparseArray<View>();
        private View convertView;
		
        public ViewHolder(View convertView) {
            this.convertView = convertView;
        }

        @SuppressWarnings("unchecked")
        public <T extends View> T getView(int resId) {
        	//从之前的集合中取一下
            View v = views.get(resId);
            //没有的话,找到并放入集合中
            if (null == v) {
                v = convertView.findViewById(resId);
                views.put(resId, v);
            }
            return (T) v;
        }
    }

    public void addAll(List<T> elem) {
        data.addAll(elem);
        notifyDataSetChanged();
    }
	
    public void remove(T elem) {
        data.remove(elem);
        notifyDataSetChanged();
    }

    public void remove(int index) {
        data.remove(index);
        notifyDataSetChanged();
    }

    public void replaceAll(List<T> elem) {
        data.clear();
        data.addAll(elem);
        notifyDataSetChanged();
    }
}

使用方法:

private ListView lv;
	private List<String> datas;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		lv = (ListView) findViewById(R.id.lv);
		datas=new ArrayList<String>();
		datas.add("1111");
		datas.add("12222");
		datas.add("133333");
		datas.add("11444444");
		lv.setAdapter(new MyAdapter(this, datas));
	}

	public class MyAdapter extends SimpleBaseAdapter<String> {

	    public MyAdapter(Context context, List<String> data) {
	        super(context, data);
	    }

	    @Override
	    public int getItemResource() {
	        return R.layout.list_item;
	    }

	    @Override
	    public View getItemView(int position, View convertView, ViewHolder holder) {
	        TextView tv = holder.getView(R.id.tv);
	        tv.setText(getItem(position).toString());  
	        return convertView;
	    }
	}

1.数据当然是一定要的了.需要通过构造传给adapter

2.adapter需要知道item的布局id,通过实现他的getItemResource()来传递.

3.getItemView很重要的方法,相当于getView的方法了.getView内部最终会调用此方法.

4.getItemView的参数holder.getView可以得到item中的某个view.实际上内部自然是findViewById,然后把得到的View存入一个集合,如果就复用,如果没用才存入集合.


让我们看看以前的写法吧.

class MyAdapter extends BaseAdapter {
		/**
		 * 可抽取
		 * @return
		 */
		@Override
		public int getCount() {
			return datas.length;
		}

		/**
		 * 把动态的抽取成一个方法,然后暴漏出去让子类实现
		 * @param position
		 * @param convertView
		 * @param parent
		 * @return
		 */
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view;
			ViewHolder holder;
			if (convertView == null) {
				view=View.inflate(MainActivity.this, R.layout.list_item, null);
				holder=new ViewHolder();
				holder.iv=(ImageView) view.findViewById(R.id.iv);
				holder.tv=(TextView) view.findViewById(R.id.tv);
				view.setTag(holder);
			} else {
				view=convertView;
				holder = (ViewHolder) view.getTag();
			}
			holder.tv.setText(datas[position]);
			return view; 
		}
		/**
		 * 可抽取
		 * @return
		 */
		@Override
		public Object getItem(int position) {
			return null;
		}
		/**
		 * 可抽取
		 * @return
		 */
		@Override
		public long getItemId(int position) {
			return 0;
		}

	}
	/**
	 * 通过拿到Item的View,自己findViewById
	 * 然后放入集合来达到抽取目的.
	 * @return
	 */
	private static class ViewHolder{
		private TextView tv;
		private ImageView iv;
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值