本文转自:http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html
如欲获得更多更好的信息,请访问原文地址,这里仅作记载
有按钮的ListView
但是有时候,列表不光会用来做显示用,我们同样可以在在上面添加按钮。添加按钮首先要写一个有按钮的xml文件,然后自然会想到用上面的方法定义一个适配器,然后将数据映射到布局文件上。但是事实并非这样,因为按钮是无法映射的,即使你成功的用布局文件显示出了按钮也无法添加按钮的响应,这时就要研究一下ListView是如何现实的了,而且必须要重写一个类继承BaseAdapter。下面的示例将显示一个按钮和一个图片,两行字如果单击按钮将删除此按钮的所在行。并告诉你ListView究竟是如何工作的。效果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/e05cd5c36a3d748b90b6db7ed584c6f7.png)
vlist2.xml
01 | <? xml version = "1.0" encoding = "utf-8" ?> |
03 | android:orientation = "horizontal" |
04 | android:layout_width = "fill_parent" |
05 | android:layout_height = "fill_parent" > |
08 | < ImageView android:id = "@+id/img" |
09 | android:layout_width = "wrap_content" |
10 | android:layout_height = "wrap_content" |
11 | android:layout_margin = "5px" /> |
13 | < LinearLayout android:orientation = "vertical" |
14 | android:layout_width = "wrap_content" |
15 | android:layout_height = "wrap_content" > |
17 | < TextView android:id = "@+id/title" |
18 | android:layout_width = "wrap_content" |
19 | android:layout_height = "wrap_content" |
20 | android:textColor = "#FFFFFFFF" |
21 | android:textSize = "22px" /> |
22 | < TextView android:id = "@+id/info" |
23 | android:layout_width = "wrap_content" |
24 | android:layout_height = "wrap_content" |
25 | android:textColor = "#FFFFFFFF" |
26 | android:textSize = "13px" /> |
31 | < Button android:id = "@+id/view_btn" |
32 | android:layout_width = "wrap_content" |
33 | android:layout_height = "wrap_content" |
34 | android:text = "@string/s_view_btn" |
35 | android:layout_gravity = "bottom|right" /> |
程序代码:
005 | public class MyListView4 extends ListActivity { |
008 | private List<Map<String, Object>> mData; |
011 | public void onCreate(Bundle savedInstanceState) { |
012 | super .onCreate(savedInstanceState); |
014 | MyAdapter adapter = new MyAdapter( this ); |
015 | setListAdapter(adapter); |
018 | private List<Map<String, Object>> getData() { |
019 | List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); |
021 | Map<String, Object> map = new HashMap<String, Object>(); |
022 | map.put( "title" , "G1" ); |
023 | map.put( "info" , "google 1" ); |
024 | map.put( "img" , R.drawable.i1); |
027 | map = new HashMap<String, Object>(); |
028 | map.put( "title" , "G2" ); |
029 | map.put( "info" , "google 2" ); |
030 | map.put( "img" , R.drawable.i2); |
033 | map = new HashMap<String, Object>(); |
034 | map.put( "title" , "G3" ); |
035 | map.put( "info" , "google 3" ); |
036 | map.put( "img" , R.drawable.i3); |
044 | protected void onListItemClick(ListView l, View v, int position, long id) { |
046 | Log.v( "MyListView4-click" , (String)mData.get(position).get( "title" )); |
052 | public void showInfo(){ |
053 | new AlertDialog.Builder( this ) |
054 | .setTitle( "我的listview" ) |
056 | .setPositiveButton( "确定" , new DialogInterface.OnClickListener() { |
058 | public void onClick(DialogInterface dialog, int which) { |
067 | public final class ViewHolder{ |
068 | public ImageView img; |
069 | public TextView title; |
070 | public TextView info; |
071 | public Button viewBtn; |
075 | public class MyAdapter extends BaseAdapter{ |
077 | private LayoutInflater mInflater; |
080 | public MyAdapter(Context context){ |
081 | this .mInflater = LayoutInflater.from(context); |
084 | public int getCount() { |
090 | public Object getItem( int arg0) { |
096 | public long getItemId( int arg0) { |
102 | public View getView( int position, View convertView, ViewGroup parent) { |
104 | ViewHolder holder = null ; |
105 | if (convertView == null ) { |
107 | holder= new ViewHolder(); |
109 | convertView = mInflater.inflate(R.layout.vlist2, null ); |
110 | holder.img = (ImageView)convertView.findViewById(R.id.img); |
111 | holder.title = (TextView)convertView.findViewById(R.id.title); |
112 | holder.info = (TextView)convertView.findViewById(R.id.info); |
113 | holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn); |
114 | convertView.setTag(holder); |
118 | holder = (ViewHolder)convertView.getTag(); |
122 | holder.img.setBackgroundResource((Integer)mData.get(position).get( "img" )); |
123 | holder.title.setText((String)mData.get(position).get( "title" )); |
124 | holder.info.setText((String)mData.get(position).get( "info" )); |
126 | holder.viewBtn.setOnClickListener( new View.OnClickListener() { |
129 | public void onClick(View v) { |
下面将对上述代码,做详细的解释,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了。
运行效果如下图:
![](https://i-blog.csdnimg.cn/blog_migrate/95b7fd86629a5f98dffdcb5ffd1af7f1.png)