关于android中ListView的Adapter如何设计能通用的一些看法

我们都知道,在安卓中使用ListView显示多条数据的时候,必须要用一个适配器作为Data和View的桥梁,这种设计非常好, 能很简单就把ui和data分离开来,为ui的复用和维护代码提供方便。
但是每次写一个适配器,都要实现一大堆的重复逻辑,其实每次getView中无非就是Holder对象不一样,加载的数据类型不一样,剩下的方法都是相同的,那么我们就可以将相同的元素抽取出来写成一个基类,整理下代码冗余。

public abstract class MyBaseAdapter extends BaseAdapter {
    Context context;
    ArrayList arrayList;
    private BaseHolder holder;

    public MyBaseAdapter(Context context) {
        this.context = context;
        arrayList = new ArrayList<>();
    }

    public Context getContext() {
        return context;
    }

    public void add(E data) {
        arrayList.add(data);
    }

    public void remove(E data) {
        arrayList.remove(data);
    }

    public void setDataSourse(ArrayList lists) {
        setDataSourse(lists, true);
    }

    public void setDataSourse(ArrayList lists, boolean isClear) {
        if (isClear) {
            arrayList.clear();
            arrayList.addAll(lists);
        }else{
            arrayList.addAll(lists);
        }
    }

    public void clear() {
        arrayList.clear();
    }

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

    @Override
    public Object getItem(int position) {
        return arrayList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        holder = null;
        if (convertView == null) {
            holder = createViewHolder();
            convertView = holder.rootView;
            if (holder == null || convertView == null) {
                throw new NullPointerException("必须有View对象,holder不能为空");
            }
            convertView.setTag(holder);
        } else {
            holder = (BaseHolder) convertView.getTag();
        }
        bindViewHolder(holder, position);
        return convertView;
    }

    public abstract T createViewHolder();

    public void bindViewHolder(BaseHolder holder, int position) {

    }

    public static class BaseHolder {
        View rootView;
        SparseArray sparseArray = new SparseArray<>();

        public BaseHolder(View rootView) {
            this.rootView = rootView;
        }

        public View getView(int RId) {
            View view = sparseArray.get(RId);
            if (view == null) {
                view = rootView.findViewById(RId);
                sparseArray.put(RId, view);
            }
            return view;
        }
    }
}

 
  
 
  
 
  
解释一下上面的代码:

我们将不同的数据对象用E来表示,T表示baseHolder的子类,具有拓展性,通过setDataSource()将传进来的数据赋值给本地的ArrayList,createViewHolder()写成抽象的目的是让用户自行设计他的返回holder格式,用户可以传不同样式的item进来,BaseHolder的构造方法,将传进来的view赋值给本地的rootView,getView()方法目的获取item内的子部件,例如:TextView,ImageView等。我们这里使用SparseArray,它的好处看下:http://blog.csdn.net/baidujiangwei18/article/details/51461382,这样我们就讲BaseAdapter解耦了,将他的数据与View分离开,bindViewHolder()主要是对子部件进行操作,例如赋值,配置图片等。

我们只需要在MainActivity当中实现bindViewHolder()与createViewHolder()即可。

public class MainActivity extends Activity {
    private ListView lv;
    private ArrayList arrayList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv = (ListView) findViewById(R.id.lv);
        for (int i = 0; i < 20; i++) {
            arrayList.add("hello"+i);
        }
        MyBaseAdapter1 myBaseAdapter1 = new MyBaseAdapter1(MainActivity.this);
        myBaseAdapter1.setDataSourse(arrayList);
        lv.setAdapter(myBaseAdapter1);
    }

    public class MyBaseAdapter1 extends MyBaseAdapter {

        public MyBaseAdapter1(Context context) {
            super(context);
        }

        @Override
        public BaseHolder createViewHolder() {
           return new BaseHolder(View.inflate(MainActivity.this, R.layout.lv_item, null));
        }

        @Override
        public void bindViewHolder(BaseHolder holder,int posiiton) {
            TextView tv = (TextView) holder.getView(R.id.tv);
            tv.setText((String)getItem(posiiton));
        }
    }

}

 好了,像listView这么基础的东西建议大家多写写。有建议或者不懂的请留言。 
  

你可能感兴趣的:(自定义View)