ListView
1.在android
开发中很多时候都要用到ListView的这个控件的,但用这个控件的时候会遇到一些问题,如在ListView中有Button按钮,就需要将按钮的监听事件给分离出来,且将Button该为自己的定义的Button控件
这只是一个思路,在进行例子之前,对一些小的知识点进行一下复习:
2.API是开发中最好的老师,它对ListView的解释是:
3.这里就对ListView运行机制做个解释(引用别人的一段话):
listView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到listView的长度(这也是为什么在开始的第一张图特
别的标出列表长度),然后根据这个长度,调用getView()逐一绘制每一行。如果你的getCount()返回值是0的话,列表将不显示同样 return
1,就只显示一行。 系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必须手动映射数据,这需要重写
getView()方法。系统在绘制列表的每一行的时候将调用此方法。getView()有三个参数,position表示将显示的是第几
行,covertView是从布局文件中inflate来的布局。我们用LayoutInflater的方法将定义好的vlist2.xml文件提取成
View实例用来显示。然后将xml文件中的各个组件实例化(简单的findViewById()方法)。这样便可以将数据对应到各个组件上了。但是按钮
为了响应点击事件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定义的listView就完成了,现在让我们回过头从新审视这个过程。系统
要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面首先获得一
个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那
再绘制下一行,直到绘完为止。在实际的运行过程中会发现listView的每一行没有焦点了,这是因为Button抢夺了listView的焦点,只要布
局文件中将Button设置为没有焦点就OK了
4.在给按钮添加OnClickListener的时候,一开始很下意识的会想在ListView的adapter的getView方法中找到每个
Button并new一个OnClickListener分配给这个button。但是当数据量很大的时候,new出来这么多个监听器势必会对内存造成一
定的压力,而且每个Listener的功能完全一样,Listener里面所需知道的
所以自定一个MyOnClickListener(用了单例模式,这样就不会造成new了很多同一个对象了)
1 public class MyOnClickListener implements OnClickListener {
2
3 private static MyOnClickListener instance;
4 private Context context;
5
6 public MyOnClickListener() {
7 }
8
9 public static MyOnClickListener instance() {
10 if (instance == null) {
11
12 instance = new MyOnClickListener();
13 }
14
15 return instance;
16 }
17
18 @Override
19 public void onClick(View v) {
20 MyButton button = (MyButton) v;
21 String userID = button.getUserID();
22 Toast.makeText(context, "所获得的用户ID为:" + userID, Toast.LENGTH_SHORT)
23 .show();
24 }
25
26 /**
27 * @return the context
28 */
29 public Context getContext() {
30 return context;
31 }
32
33 /**
34 * @param context
35 * the context to set
36 */
37 public void setContext(Context context) {
38 this.context = context;
39 }
40
41 }
5.因为要从外面获取参数别进行处理,而处理是交给MyOnClickListener的,而MyOnClickLister能获取到的就是Button了,这时就需要一个自己定的Button(MyButton)来获取到外部数据:
MyButton:
1 public class MyButton extends Button {
2
3 private String userID;
4
5 public MyButton(Context context) {
6 super(context);
7 }
8
9 public MyButton(Context context, AttributeSet attrs) {
10 super(context, attrs);
11 }
12
13 public MyButton(Context context, AttributeSet attrs, int defstyle) {
14 super(context, attrs, defstyle);
15 }
16
17 /**
18 * @return the userID
19 */
20 public String getUserID() {
21 return userID;
22 }
23
24 /**
25 * @param userID
26 * the userID to set
27 */
28 public void setUserID(String userID) {
29 this.userID = userID;
30 }
31
32 }
6.主要的两个类都完成了,现在就是很普通的一些东西了
MianActivity:
1 public class MainActivity extends Activity {
2
3 private ListView listView;
4 private List<HashMap<String, Object>> list;
5
6 @Override
7 protected void onCreate(Bundle savedInstanceState) {
8 super.onCreate(savedInstanceState);
9 setContentView(R.layout.activity_main);
10 initData();
11 listView = (ListView)findViewById(R.id.listView);
12 MyAdapter adapter = new MyAdapter();
13 listView.setAdapter(adapter);
14 }
15
16 private void initData() {
17 list = new ArrayList<HashMap<String, Object>>();
18 HashMap<String, Object> map1 = new HashMap<String, Object>();
19 map1.put("image", R.drawable.ic_launcher);
20 map1.put("userID", "1");
21 HashMap<String, Object> map2 = new HashMap<String, Object>();
22 map2.put("image", R.drawable.ic_launcher);
23 map2.put("userID", "2");
24 HashMap<String, Object> map3 = new HashMap<String, Object>();
25 map3.put("image", R.drawable.ic_launcher);
26 map3.put("userID", "3");
27 HashMap<String, Object> map4 = new HashMap<String, Object>();
28 map4.put("image", R.drawable.ic_launcher);
29 map4.put("userID", "4");
30 HashMap<String, Object> map5 = new HashMap<String, Object>();
31 map5.put("image", R.drawable.ic_launcher);
32 map5.put("userID", "5");
33 list.add(map1);
34 list.add(map2);
35 list.add(map3);
36 list.add(map4);
37 list.add(map5);
38
39 }
40
41 public class MyAdapter extends BaseAdapter {
42
43 @Override
44 public int getCount() {
45 return list.size();
46 }
47
48 @Override
49 public Object getItem(int position) {
50 return list.get(position);
51 }
52
53 @Override
54 public long getItemId(int position) {
55 return position;
56 }
57
58 @Override
59 public View getView(int position, View convertView, ViewGroup parent) {
60 View view = LayoutInflater.from(MainActivity.this).inflate(
61 R.layout.item, null);
62 TextView textView = (TextView) view.findViewById(R.id.userID);
63 textView.setText((CharSequence) list.get(position).get("userID"));
64 MyButton button = (MyButton) view.findViewById(R.id.button);
65 button.setUserID((String) list.get(position).get("userID"));
66 button.setOnClickListener(MyOnClickListener.instance());
67 MyOnClickListener.instance().setContext(MainActivity.this);
68 return view;
69 }
70
71 }
72
73 @Override
74 public boolean onCreateOptionsMenu(Menu menu) {
75 getMenuInflater().inflate(R.menu.main, menu);
76 return true;
77 }
78
79 }
7.ListView中的每个item布局文件
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/image"
9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 android:src="@drawable/ic_launcher" />
12
13 <TextView
14 android:id="@+id/userID"
15 android:layout_width="wrap_content"
16 android:layout_height="wrap_content"
17 android:text="用户ID" />
18
19 <com.example.listview.MyButton
20 android:id="@+id/button"
21 android:layout_width="wrap_content"
22 android:layout_height="wrap_content"
23 android:text="显示ID" />
24
25 </LinearLayout>
MianActivity就不贴出来了,他里面就一个 ListView
运行后的效果是:
当点击第三个按钮的时候,弹出对应的数字:
ListView中button点击事件盖掉onItemClick解决办法在:这里可以查看到
源码下载:下载
android ListView进阶