向 ListView中绑定数据里,一定只需要使用SimpleAdater及可, 但如果 ListView 中的Item中有Button的话,就无法向这个Button来绑定事件了. 这时我们只能自己去实现一个 Adapter了,
写一个类继承自 BaseAdapter ,重写里面的4个方法.
这个例子实现了, Item内的Button的事件绑定及 对ListView的优化 (包括重复使用 converView,及 ViewHolder类来保存Item中的子控件,这样就极大的降低了findViewById的使用,并且也方便了子控件的调用... 技巧)
点击 Item会显示/隐藏 下面的Button. 详细可以看 下面代码的注释
1 package com.example.listviewtest; 2 3 import java.util.ArrayList; 4 5 public class MainActivity extends Activity { 6 private ListView listView = null; 7 private List<HashMap<String, String>> list = null; 8 9 @Override 10 protected void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.activity_main); 13 14 // Get UI 15 listView = (ListView) findViewById(R.id.listView1); 16 17 // Fill List 18 list = new ArrayList<HashMap<String, String>>(); 19 for (int i = 0; i < 4; i++) { 20 HashMap<String, String> map = new HashMap<String, String>(); 21 map.put("name", "这是第 " + i + " 行"); 22 list.add(map); 23 } 24 25 // 绑定我们自定义的 Adapter 26 listView.setAdapter(new MyAdapter(this)); 27 28 // 设置 ListView的 ItemClick 事件 29 listView.setOnItemClickListener(new OnItemClickListener() { 30 @Override 31 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { 32 // TODO Auto-generated method stub 33 System.out.println("你点击了 List中的第 " + arg2 + " 个 Item"); 34 35 // 我们可以直接通过.Tag得到它的子控件 36 ViewHolder holder = (ViewHolder)arg1.getTag(); 37 38 // 这里是将,下面的一个Button 显示(0)/隐藏(8) 39 int val = holder.hideButton.getVisibility(); 40 if (val == 8) { 41 holder.hideButton.setVisibility(0); 42 } else { 43 holder.hideButton.setVisibility(8); 44 } 45 } 46 }); 47 } 48 49 // 创建一个 ViewHolder 类 50 // 用来存储 list_item_layout.xml中下义的View控件. 51 // 并把这个ViewHolder对象放到Item的Tag中, 52 // 这样做极大了方便我们之后对Item中的控件的修改操作 53 // 并大大的减少了 findViewById的次数,提高效率 54 class ViewHolder { 55 public ImageView img; 56 public TextView text; 57 public Button button; 58 public Button hideButton; 59 } 60 61 // 创建自定义的 Adapter 62 class MyAdapter extends BaseAdapter { 63 // LayoutInflater 可以根据XML,加载View 64 private LayoutInflater inflater = null; 65 66 public MyAdapter(Context context) { 67 // 使用LayoutInflater.from(Context)方法, 得到LayoutInflater 68 // 包括直接在Activtity中使用 getLayoutInflater 都是调用的下面的这个方法 69 // (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE) 70 inflater = LayoutInflater.from(context); 71 } 72 73 // 得到ListView中Item的数量 74 @Override 75 public int getCount() { 76 // TODO Auto-generated method stub 77 return list.size(); 78 } 79 80 // 下面这两个方法. 一般不用重写,主要是用来使用Adapter 得到相应的View用的. 81 // 我们还不需要这样的操作,所以可以保持默认,不用去实现 82 @Override 83 public Object getItem(int arg0) { 84 // TODO Auto-generated method stub 85 return null; 86 } 87 88 @Override 89 public long getItemId(int arg0) { 90 // TODO Auto-generated method stub 91 return 0; 92 } 93 94 // 这是 主要去实现的方法 这个方法的做用就是通过你定义好的 list_item_layout.xml得到View对象. 95 // 设置 View 中相应的数据内容,及绑定一些事件等等 . 96 // 这里使用 ViewHolder做了优化. 将ViewHolder放到View的Tag中. 这样极大的方便了我们修改相应的View控件,并且减少了findViewById的次数,提高ListView的效率. 97 @Override 98 public View getView(int position, View convertView, ViewGroup parent) { 99 // 声明一个 ViewHolder对象 100 ViewHolder holder = null; 101 102 // convertView .就是上一次使用的Item的View对象, 参数View convertView 而这个convertView其实就是最关键的部分了 原理上讲 103 // 当ListView滑动的过程中 会有item被滑出屏幕 而不再被使用 这时候Android会回收这个条目的view ,当item1被移除屏幕的时候 我们会重新new一个View给新显示的item_new 104 // 而如果使用了这个convertView 我们其实可以复用它 这样就省去了new View的大量开销 105 // 如果没有可用的 convertView 那么就要创建它 106 if (convertView == null) { 107 // 创建一个 ViewHolder对象,来保存这个 View中的了控件,这样,我们就不需要每都用 使用findViewById了. 108 holder = new ViewHolder(); 109 // 使用 LayoutInflater 创建View 110 convertView = inflater.inflate(R.layout.list_item_layout, null); 111 // 将,View 的了控件保存到 holder 中. 112 holder.img = (ImageView)convertView.findViewById(R.id.imageView1); 113 holder.text = (TextView)convertView.findViewById(R.id.textView1); 114 holder.button = (Button)convertView.findViewById(R.id.button2); 115 holder.hideButton = (Button)convertView.findViewById(R.id.button3); 116 // 将Hodler 存放在 convertView 的 Tag 中. 117 convertView.setTag(holder); 118 } else { 119 // 如果有可用的 convertView.那么就得到存在它Tag中的 Holder对象 120 holder = (ViewHolder)convertView.getTag(); 121 } 122 123 // 对Holder对象中的控制设置属性或绑定事件 124 holder.img.setImageResource(R.drawable.ic_launcher); 125 holder.text.setText(list.get(position).get("name")); 126 holder.button.setTag(position); 127 holder.button.setOnClickListener(new OnClickListener() { 128 @Override 129 public void onClick(View v) { 130 // TODO Auto-generated method stub 131 System.out.println("你点击了第 " + v.getTag() + " 个Item中的Button"); 132 } 133 }); 134 135 // 将这个 converView 返回 136 return convertView; 137 } 138 } 139 140 @Override 141 public boolean onCreateOptionsMenu(Menu menu) { 142 // Inflate the menu; this adds items to the action bar if it is present. 143 getMenuInflater().inflate(R.menu.main, menu); 144 return true; 145 } 146 147 }