Android开发之万能适配器

ListView、GridView等等非常多的东西都需要适配器。而如果开发一个app每一个listview都有写一个Adapter的话,那还怎么愉快的玩游戏。。

什么是ViewHolider以及的用法和为什么要用?

这位博主写的非常好。

http://www.cnblogs.com/lichenwei/p/4085107.html

所谓的万能适配器,无非是将适配器的重复代码抽取出来进行封装。不同功能的代码则留写一个方法留给用户复写,则每个listview的适配器就只变成几句话就够了。

这是一般适配器的代码:

private class MyAdapter extends BaseAdapter
    {

        private Context mcontext=null;
        private LayoutInflater inflater;
        
        public MyAdapter(Context c)
        {
            this.mcontext=c;
            this.inflater=LayoutInflater.from(c);//from告诉系统从哪里获得布局填充器
        }
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return mListTitle.length;
        }

        @Override
        public Object getItem(int arg0) {
            // TODO Auto-generated method stub
            return arg0;
        }

        @Override
        public long getItemId(int arg0) {
            // TODO Auto-generated method stub
            return arg0;
        }

        @Override
        public View getView(int arg0, View arg1, ViewGroup arg2) {
            // TODO Auto-generated method stub
            ViewHolder viewholder =null;
            if (arg1==null)
            {
                viewholder=new ViewHolder();
                arg1=inflater.inflate(R.layout.iconlist, arg2, false);
                viewholder.iv=(ImageView)arg1.findViewById(R.id.imageview);
                viewholder.title=(TextView)arg1.findViewById(R.id.title);
                viewholder.text=(TextView)arg1.findViewById(R.id.text);
                arg1.setTag(viewholder);
            }
            else
            {
                viewholder=(ViewHolder)arg1.getTag();
            }
            viewholder.iv.setImageResource(R.drawable.icon1);
            viewholder.title.setText(mListTitle[arg0]);
            viewholder.text.setText(mListStr[arg0]);
            return arg1;
        }
        
    }
    private class ViewHolder
    {
        private ImageView iv=null;
        private TextView title=null;
        private TextView text=null;
    }

首先我们先对ViewHolder进行封装:

1、ViewHolder将xml文件转换成convertview,并将转换后的view返回

2、要设置标签

3、判断convertview是否为空,空的话重新new创建,不为空的话getTag();

代码:

 1 package com.example.list_view;
 2 import android.content.Context;
 3 import android.util.SparseArray;
 4 import android.view.LayoutInflater;
 5 import android.view.View;
 6 import android.view.ViewGroup;
 7 
 8 public class easyViewHolder {
 9 
10     private SparseArray<View> sparseArray;
11     private Context context;
12     private int LayoutId;
13     private View convertview;
14     public easyViewHolder(Context mcontext,View mconvertview,int LayoutId,ViewGroup parent)
15     {
16         this.context=mcontext;
17         this.sparseArray=new SparseArray<View>();
18         this.convertview=LayoutInflater.from(mcontext).inflate(LayoutId, parent, false);
19         convertview.setTag(this);    
20     }
21     public static easyViewHolder get(Context context,View convertview,int LayoutId,ViewGroup parent)
22     {
23         if (convertview==null)
24         {
25             return new easyViewHolder(context, convertview, LayoutId, parent);
26         }
27         
28         
29             // 特别需要注意的一点,由于ListView的复用,比如屏幕只显示5个Item,那么当下拉到第6个时会复用第1个的Item,所以这边需要更新position
30             return  (easyViewHolder)convertview.getTag();
31         
32     }
33     public <T extends View> T getView(int viewId)//通过id找到组件
34     {
35         View view = sparseArray.get(viewId);
36         if (view==null)
37         {
38             view=(View)this.convertview.findViewById(viewId);
39             sparseArray.put(viewId, view);
40         }
41         return (T)view;
42         
43     }
44     public View getConvertView()
45     {
46         return this.convertview;
47     }
48 }

再封装一个适配器:

声明一个抽象类

1、保留不变的方法

2、修改getview()

3、写一个需要重写函数用来给用户传值。

 1 package com.example.list_view;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import android.content.Context;
 7 import android.view.LayoutInflater;
 8 import android.view.View;
 9 import android.view.ViewGroup;
10 import android.widget.BaseAdapter;
11 
12 public abstract class easyAdapter<T> extends BaseAdapter {
13 
14     private Context context;
15     private ArrayList<T> data;
16     private LayoutInflater inflater;
17     private int LayoutId;
18     easyViewHolder easyholder;
19     public easyAdapter( Context context,ArrayList<T> data,int layoutid)
20     {
21         this.context=context;
22         this.data=data;
23         inflater.from(context);
24         this.LayoutId=layoutid;
25     }
26     @Override
27     public int getCount() {
28         // TODO Auto-generated method stub
29         return data.size();
30     }
31 
32     @Override
33     public Object getItem(int arg0) {
34         // TODO Auto-generated method stub
35         return arg0;
36     }
37 
38     @Override
39     public long getItemId(int arg0) {
40         // TODO Auto-generated method stub
41         return arg0;
42     }
43 
44     @Override
45     public View getView(int arg0, View arg1, ViewGroup arg2) {
46         // TODO Auto-generated method stub
47         final easyViewHolder easyholder=getHolder(context, arg1, LayoutId, arg2);
48         setConverView(easyholder,data.get(arg0));//需要用户复写传值
49         return easyholder.getConvertView();
50     }
51      public abstract void setConverView(easyViewHolder easyViewHolder, T t);
52      public static easyViewHolder getHolder(Context context,View convertview,int LayoutId,ViewGroup parent)
53     {
54             return easyViewHolder.get(context, convertview, LayoutId, parent);
55     }
56 }

以上的两个类除了添加新功能不用在对其改变。

接下来我们就可以以最少的代码完成适配器:

 1 package com.example.list_view;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import android.content.Context;
 7 import android.widget.ImageView;
 8 import android.widget.TextView;
 9 
10 public class MyAdapter extends easyAdapter<User> {
11 
12     public MyAdapter(Context context, ArrayList<User> data, int layoutId) {
13         super(context, data, layoutId);
14         // TODO Auto-generated constructor stub
15     }
16 //只需在下面函数传入你所需要的值
17     public void setConverView(easyViewHolder myViewHolder, User t) {
18         // TODO Auto-generated method stub
19         
20         ((ImageView)myViewHolder.getView(R.id.imageview)).setImageResource(R.drawable.icon1);
21         ((TextView)myViewHolder.getView(R.id.title)).setText(t.getTitle());
22         ((TextView)myViewHolder.getView(R.id.text)).setText(t.getText());
23         
24     }
25 
26 }

MainActivity的代码:

for (int i=0;i<10;i++)
{
User user=new User();
user.setIv(R.drawable.icon1);
user.setTitle("用户"+i);
user.setText("1000"+i);
list.add(user);
}
MyAdapter adapter=new MyAdapter(MainActivity.this, list, R.layout.iconlist);
list1.setAdapter(adapter);

只是单纯传入你这个listview所需要的数据源,以及传入listview的布局,便可完成各式各样的listview。

posted @ 2015-09-15 02:10  h_shy  阅读(439)  评论(0编辑  收藏  举报