转载请备注出自于:


1.Android ArrayAdapter 详解

一、简单的。

这样的列表的每一行都只有一行文字。

1. ListView list = (ListView)findViewById(R.id.list);  
2. " 百色学院","android技术开发","9701"};  
3.  构造函数:public ArrayAdapter (Context context, int textViewResourceId, T[] objects) 
4.          ArrayAdapter <String>arrayAdapter = new ArrayAdapter<String>( this,android.R.layout.simple_list_item1,arr);  
5. //为ListView设置Adapter  
6. 
7. 第一个参数是上下文context,就是当前的Activity,一般为this, 第二个参数是android sdk中自己内置的一个布局,它里面只有一个TextView,这个参数是表明我们数组中每一条数据都一一对应显示在这个view上面;第三个参数就是我们要显示的数据。listView会根据这三个参数,遍历数据源(如数组)里面的每一条数据,读出一条,显示到第二个参数对应的布局中。
8. 
9.  
  Android SDK中自己内置的一个布局如下: 
   
 
  simple_list_item_1:TextView 
   
 
  simple_list_item_2:TextView(字体略大); 
   
  simple_list_item_checked:每个列表项都是一个已勾选的列表项。 
   
  simple_list_item_multiple_choice:每个列表都是带多选框的文本。 
   
  simple_list_item_single_choice:每个列表项都是带多单选按钮的文本。

1. <LinearLayout  
2. android:orientation="horizontal"  
3. andrlod:layout_width="match_parent"  
4. android:layout_height="match_parent">  
5. <ImageView  
6. android:id="@+id/image"  
7.                ......    
8. />  
9.   
10.   
11. <TextView  
12.                android:id="@+id/title"
13. 
14.                /> 
15. <LinearLayout>

二、样式丰富但内容简单的。

layout下的online_user_list_item.xml内容如下:


1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"  
3. android:layout_width="fill_parent"  
4. android:layout_height="wrap_content">  
5. <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"  android:id="@+id/online_user_list_item_textview" android:text="TextView"></TextView>  
6. <Button  
7. android:text="button"  
8. android:layout_width="wrap_content"  
9. android:layout_height="wrap_content">  
10. </Button>  
11. </LinearLayout>



里面含有的textview是我们想要展示内容的地方。那么构建ArrayAdapter时,应该这样写:

1. ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.online_user_list_item, R.id.online_user_list_item_textview);

如果我们需要展示的内容是一仅一个textview承载不了的,还需要其它组件,怎么办?我们可以自定义。

三、内容丰富的(自定义ArrayAdapter)。

这就需要写一个类继承自ArrayAdapter并且重写getView方法。上代码:


1. public class UserListAdapter extends ArrayAdapter<User> {  
2. private int resourceId;  
3. public UserListAdapter(Context context, int textViewResourceId, List<User> objects) {  
4. super(context, textViewResourceId, objects);  
5. this.resourceId = textViewResourceId;  
6.     }  
7.       
8. @Override  
9. public View getView(int position, View convertView, ViewGroup parent){  
10.         User user = getItem(position);  
11. new LinearLayout(getContext());  
12.         String inflater = Context.LAYOUT_INFLATER_SERVICE;   
13.         LayoutInflater vi = (LayoutInflater)getContext().getSystemService(inflater);   
14. true);  
15.         TextView tvUsername = (TextView)userListItem.findViewById(R.id.tv_user_list_username);  
16.         TextView tvAskedNum = (TextView)userListItem.findViewById(R.id.tv_user_list_askednum);  
17.         TextView tvLastMsg = (TextView)userListItem.findViewById(R.id.tv_user_list_lastmsg);  
18.         tvUsername.setText(user.getUsername());  
19.         tvAskedNum.setText(String.valueOf(user.getAskedNum()));  
20.         tvLastMsg.setText(user.getLastMsg());  
21. return userListItem;  
22.     }  
23. }


activity里就这样写

1. List<User> users = new ArrayList<User>();  
2. new User();  
3. 8);  
4. "hello");  
5. "pxx");  
6.         users.add(user);  
7.         users.add(user);  
8.         users.add(user);  
9. new UserListAdapter(this,R.layout.online_user_list_item,users);  
10.         listview.setAdapter(adapter);


2.Android SimpleAdapter 详解


1. listView listview = (ListView)findViewById(R.id.listView1);  
2.   
3. int[] imageId = new int[]{R.drawable.imag0,R.drawable.imag1,R.drawable.imag2};  
4.   
5. String[] title = new String[]{"百色学院","android技术开发","电气13班"};  
6.   
7. List<Map<String,Object>>listItems = new ArrayList<Map<String,Object>>();//创建一个List集合  
8.   
9. for(int i=0;i<imageld.length;i++){//遍历数组  
10.   
11. new HashMap<String,Object>();//创建哈希表  
12.   
13. "image",imageId[i]);  
14.   
15. "title",title[i]);  
16.   
17.     listItems.add(map);}  
18.   
19. SimpleAdapter adapter = new SimpleAdapter(this,listItems,R.layout.items,new String[]{"title","image"},new  
20.   
21. int[]{"R.id.title","R.id.image"});   
22.   
23. listView.setAdapter(adapter); 
24. 构造参数:
25. SimpleAdapter(Context  context, List<? extends Map<String, ?>>  data, int resource, String[]  from, int[] to)
      1,context:上下文。
      2,data:基于Map的list。Data里边的每一项都和 ListView里边的每一项对应。Data里边的每一项都是一个Map类型,这个Map类里边包含了ListView每一行需要的数据。
      3,resource :就是一个布局layout,可引用系统提供的,也可以自定义。
Map对象的key
to表示组件的id

3.Android BaseAdapter 详解

list_item.xml


1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3. android:layout_width="match_parent"  
4. android:layout_height="match_parent"  
5. android:orientation="horizontal" >  
6.   
7. <ImageView  
8. android:id="@+id/img"  
9. android:layout_width="wrap_content"  
10. android:layout_height="wrap_content"  
11. />  
12. <LinearLayout   
13. android:layout_width="fill_parent"  
14. android:layout_height="wrap_content"  
15. android:orientation="vertical"  
16. >  
17. <TextView  
18. android:id="@+id/tv"  
19. android:layout_width="wrap_content"  
20. android:layout_height="wrap_content"  
21. android:textSize="20sp"  
22. />  
23. <TextView   
24. android:id="@+id/info"  
25. android:layout_width="wrap_content"  
26. android:layout_height="wrap_content"  
27. android:textSize="14sp"  
28. />  
29. </LinearLayout>  
30.       
31.   
32. </LinearLayout>

当系统开始绘制ListView的时候,首先调用getCount()方法。得到它的返回值,即ListView的长度。然后系统调用getView()方法,根据这个长度逐一绘制ListView的每一行。也就是说,如果让getCount()返回1,那么只显示一行。而getItem()和getItemId()则在需要处理和取得Adapter中的数据时调用。那么getView如何使用呢?如果有10000行数据,就绘制10000次?这肯定会极大的消耗资源,导致ListView滑动非常的慢,那应该怎么做呢?

ListView优化:通过convertView+ViewHolder来实现,ViewHolder就是一个静态类,使用 ViewHolder 的关键好处是缓存了显示数据的视图(View),加快了 UI 的响应速度。当我们判断 convertView == null  的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件)。再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。(看下面代码中)如果convertView不为空的时候,就会直接用convertView的getTag(),来获得一个ViewHolder。也就是说convertView相当于一个缓存,开始为0,当有条目变为不可见,它缓存了它的数据,后面再出来的条目只需要更新数据就可以了,这样大大节省了系统资料的开销。当convertView为空时,用setTag()方法为每个View绑定一个存放控件的ViewHolder对象。当convertView不为空,重复利用已经创建的view的时候,使用getTag()方法获取绑定的ViewHolder对象,这样就避免了findViewById对控件的层层查询,而是快速定位到控件。



Activity

1. package com.demo;  
2.   
3. import java.util.ArrayList;  
4. import java.util.HashMap;  
5. import java.util.List;  
6. import java.util.Map;  
7.   
8. import android.app.Activity;  
9. import android.content.Context;  
10. import android.os.Bundle;  
11. import android.view.LayoutInflater;  
12. import android.view.View;  
13. import android.view.ViewGroup;  
14. import android.widget.BaseAdapter;  
15. import android.widget.ImageView;  
16. import android.widget.ListView;  
17. import android.widget.TextView;  
18.   
19. public class DemoActivity extends Activity {  
20. private ListView lv;  
21. private List<Map<String, Object>> data;  
22. @Override  
23. public void onCreate(Bundle savedInstanceState) {  
24. super.onCreate(savedInstanceState);  
25.         setContentView(R.layout.main);  
26.         lv = (ListView)findViewById(R.id.lv);  
27. //获取将要绑定的数据设置到data中  
28.         data = getData();  
29. new MyAdapter(this);  
30.         lv.setAdapter(adapter);  
31.     }  
32.       
33. private List<Map<String, Object>> getData()  
34.     {  
35. new ArrayList<Map<String, Object>>();  
36.         Map<String, Object> map;  
37. for(int i=0;i<10;i++)  
38.         {  
39. new HashMap<String, Object>();  
40. "img", R.drawable.ic_launcher);  
41. "title", "android");  
42. "info", "自定义adaper...");  
43.             list.add(map);  
44.         }  
45. return list;  
46.     }  
47.       
48. //ViewHolder静态类  
49. static class ViewHolder  
50.     {  
51. public ImageView img;  
52. public TextView title;  
53. public TextView info;  
54.     }  
55.       
56. public class MyAdapter extends BaseAdapter  
57.     {      
58. private LayoutInflater mInflater = null;  
59. private MyAdapter(Context context)  
60.         {  
61. //根据context上下文加载布局,这里的是Demo17Activity本身,即this  
62. this.mInflater = LayoutInflater.from(context);  
63.         }  
64.   
65. @Override  
66. public int getCount() {  
67.             //在此适配器中所代表的数据集中的条目数  
68. return data.size();  
69.         }  
70.   
71. @Override  
72. public Object getItem(int position) {  
73.            //获取数据集中与指定索引对应的数据项  
74. return position;  
75.         }  
76.   
77. @Override  
78. public long getItemId(int position) {  
79.             //获取在列表中与指定索引对应的行id  
80. return position;  
81.         }  
82.           
83.            //获取一个在数据集中指定索引的视图来显示数据  
84. @Override  
85. public View getView(int position, View convertView, ViewGroup parent) {  
86. null;  
87. //如果缓存convertView为空,则需要创建View  
88. if(convertView == null)  
89.             {  
90. new ViewHolder();  
91. //根据自定义的Item布局加载布局  
92. null);  
93.                 holder.img = (ImageView)convertView.findViewById(R.id.img);  
94.                 holder.title = (TextView)convertView.findViewById(R.id.tv);  
95.                 holder.info = (TextView)convertView.findViewById(R.id.info);  
96. //将设置好的布局保存到缓存中,并将其设置在Tag里,以便后面方便取出Tag  
97.                 convertView.setTag(holder);  
98. else  
99.             {  
100.                 holder = (ViewHolder)convertView.getTag();  
101.             }  
102. "img"));  
103. "title"));  
104. "info"));  
105.               
106. return convertView;  
107.         }  
108.           
109.     }  
110. }