Android 开发笔记七 BaseAdpater 的使用及优化方法

向 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 }

 

posted @ 2013-03-26 11:48  easyfrog  阅读(471)  评论(0编辑  收藏  举报