首页 > 代码库 > android ListView进阶

android ListView进阶

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解决办法在:这里可以查看到

源码下载下载