Android技术18:Android中Adapter类详解

1.Adapter设计模式 

    Android中adapter接口有很多种实现,例如,ArrayAdapter,BaseAdapter,CursorAdapter,SimpleAdapter,SimpleCursorAdapter等,他们分别对应不同的数据源。例如,ArrayAdater对应List和数组数据源,而CursorAdapter对应Cursor对象(一般从数据库中获取的记录集)。这些Adapter都需要getView方法返回当前列表项显示的View对象。当Model发生改变时,会调用BaseAdapter.notifyDataSetChanged方法通知组件数据已经改变,这时Adapter会调用getView方法用于重新显示组件中的内容。当组件中显示的数据变化时,如删除一个项表项,组件回调Adapter中getView方法用于重新显示组件中的内容。当组件中显示的数据变化时,如删除一个项表项,组件会通知Adapter中方法删除Model中相应的记录,然后再调用BaseAdapter.notifyDataSetChanged方法使组件中显示数据发生变化。总之一句话,无论数据变化还是组件显示数据发送变化,都需要将Adpter作为桥梁来达到View和Model之间同步的目的。

      Android中Adapter是非常明显的MVC模式。

2.Adapter内部实现原理

下面我们以ListView和BaseAdapter为例,说明其原理。

原理:ListView中List的每个item,向adapter请求一个视图View,然后Adapter中getView方法创建一个新的或从缓存区中获取View修改ViewHoler内容,然后显示。Android中为我们提供了View缓存并不是每个新的item需要新建一个新视图,Android中通过有个叫做Recycler的构件实现。

通过上图可知,AndroidListView只在刚开始convertView为空时,才创建新的View。这既减轻了内存的压力,又提高的ListView滑动时的更新的性能和用户体验。

3.代码演示

ListView+BaseAdapter,MyAdaoter继承BaseAdapter,实现其方法,关键在getView()。

 1 class MyAdapter extends BaseAdapter{
 2 
 3         private List<Map<String,String>> datas=new ArrayList<Map<String,String>>();
 4         private LayoutInflater mInflater; 
 5         private static final int TYPE_ITEM = 0;  
 6         private static final int TYPE_SEPARATOR = 1;  
 7         private static final int TYPE_MAX_COUNT = TYPE_SEPARATOR + 1;  
 8         private TreeSet mSeparatorsSet = new TreeSet();  
 9          
10         public MyAdapter() {
11             mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
12         }
13         //添加项目
14         public void add(Map<String,String> item){
15             datas.add(item);
16             notifyDataSetChanged();
17         }
18         //添加分割栏
19         public void addSeparator(Map<String,String> item){
20             datas.add(item);
21             mSeparatorsSet.add(datas.size()-1);
22             notifyDataSetChanged();
23         }
24         @Override
25         public int getItemViewType(int position) {
26             return mSeparatorsSet.contains(position)?TYPE_SEPARATOR:TYPE_ITEM;
27         }
28         
29         @Override
30         public int getViewTypeCount() {
31             return TYPE_MAX_COUNT;
32         }
33         @Override
34         public int getCount() {
35             return datas.size();
36         }
37 
38         @Override
39         public Object getItem(int position) {
40         
41             return datas.get(position);
42         }
43 
44         @Override
45         public long getItemId(int position) {
46             
47             return position;
48         }
49 
50         @Override
51         public View getView(int position, View convertView, ViewGroup parent) {
52             View view=convertView;
53             int type=getItemViewType(position);
54             ViewHolder viewHolder=null;
55             ViewHolder1 viewHolder1=null;
56             if(view==null){
57                 if(type==TYPE_ITEM){
58                     
59                     view=mInflater.inflate(R.layout.item1, null);
60                     viewHolder=new ViewHolder();
61                     viewHolder.textview1=(TextView) view.findViewById(R.id.title);
62                     viewHolder.textview2=(TextView) view.findViewById(R.id.num);
63                     view.setTag(viewHolder);//View中的setTag(Onbect)表示给View添加一个格外的数据,以后可以用getTag()将这个数据取出来。
64                 }else{
65                     view=mInflater.inflate(R.layout.item2, null);
66                     viewHolder1=new ViewHolder1();
67                     viewHolder1.textview1=(TextView)view.findViewById(R.id.title);
68                     view.setTag(viewHolder1);
69                 }
70             }
71             
72             if(type==TYPE_ITEM){
73                 viewHolder=(ViewHolder) view.getTag();
74                 viewHolder.textview1.setText(datas.get(position).get("title"));
75                 viewHolder.textview2.setText(datas.get(position).get("num"));
76             }else{
77                 viewHolder1=(ViewHolder1) view.getTag();
78                 viewHolder1.textview1.setText(datas.get(position).get("title"));
79                 view.setBackgroundColor(Color.BLUE);
80             }
81             return view;
82         }
83             
84     }
1 public static class ViewHolder{
2         public TextView textview1;
3         public TextView textview2;
4 }
5     
6 public static class ViewHolder1{
7         public TextView textview1;
8 }

ViewHolder,ViewHolder1分别对应两种不同视图,一种item,一种分割栏

item1.xml

 1 <LinearLayout
 2      xmlns:android="http://schemas.android.com/apk/res/android"
 3      android:layout_width="fill_parent"
 4      android:layout_height="fill_parent"
 5      android:padding="10dip">
 6     
 7     <TextView 
 8         android:id="@+id/title"
 9         android:layout_width="fill_parent"
10         android:layout_height="wrap_content"
11         android:gravity="left"
12         android:textSize="18sp"
13         android:layout_weight="1"/>
14     <TextView 
15         android:id="@+id/num"
16         android:layout_width="fill_parent"
17         android:layout_height="wrap_content"
18         android:gravity="center_horizontal"
19         android:textSize="18sp"
20         android:layout_weight="1"/>
21 </LinearLayout>

item2.xml

 1 <LinearLayout
 2      xmlns:android="http://schemas.android.com/apk/res/android"
 3      android:layout_width="fill_parent"
 4      android:layout_height="fill_parent">
 5     
 6     <TextView 
 7         android:id="@+id/title"
 8         android:gravity="left"
 9         android:textSize="22sp"
10         android:background="#BCD2EE"
11         android:layout_width="fill_parent"
12         android:layout_height="wrap_content"
13         android:padding="5dip"
14     />
15 
16 </LinearLayout>

初始化数据

 1 private void init(MyAdapter adapter){
 2         Map<String,String> map=null;
 3         for(int i=0;i<100;i++){
 4             if(i%5!=0){
 5             map=new HashMap<String, String>();
 6             map.put("title", "title"+i);
 7             map.put("num", "num"+i);
 8             adapter.add(map);
 9             }else{
10                 map=new HashMap<String, String>();
11                 map.put("title", "S"+i/5);
12                 adapter.addSeparator(map);
13             }
14         }
15     }

显示效果

 

Android技术18:Android中Adapter类详解,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。