ListView功能总结

ListView中最重要的就是adapter,他是listview和待显示数据之间的桥梁,他是用来对相应的UI填充数据的,其实很多UI空间都需要adapter,常见的listview,gallery等等。引用网上随处的可见的一个图来表示一下

 
这就是适配器的作用,常用的adapter有简单的arraydapter,有一点扩展性的simpleadapter,带游标的simplecursoradapter,和扩展性灵活性很强的basedapter。下面一一解说:

(1)ArrayAdapter:最简单的adpter
    实现这个adapter只要一行代码,一个字符串数组即可。其实它也可以支持图片,但是你要重写getView方法来返回你要的view,不过我感觉这样还不如直接去用simpleadapter了。

 1 public class ListViewTestActivity extends Activity {   
 2     public ListView listview;     
 3     public String[] str = {"Java", "C", "c++", "PHP", "C#"};    
 4     /** Called when the activity is first created. */     
 5     @Override     
 6     public void onCreate(Bundle savedInstanceState) {          
 7         super.onCreate(savedInstanceState);         
 8         setContentView(R.layout.main);         
 9         listview= (ListView)findViewById(R.id.list);      
10         ArrayAdapter<String> aa = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, str);      
11         listview.setAdapter(aa);         
12         listview.setOnItemClickListener(new OnItemClickListener() {      
13             @Override            
14             public void onItemClick(AdapterView<?> parent, View view, int position, long id ) {   
15                 // TODO Auto-generated method stub             
16                 Toast.makeText(ListViewTestActivity.this, (String)listview.getItemAtPosition(position), Toast.LENGTH_SHORT).show();           
17             }      
18         });    
19     }  
20 } 

(2)SimpleAdapter:使用自定义的layout来填充list的每一行,通过一个map<string.object>将对应的组件和资源相对应。

 1 public class ListViewActivity extends Activity {            
 2     public ListView listview;    
 3     /** Called when the activity is first created. */  
 4     @Override   
 5     public void onCreate(Bundle savedInstanceState) {   
 6         super.onCreate(savedInstanceState);     
 7         setContentView(R.layout.main);      
 8         listview= (ListView)findViewById(R.id.list);  
 9         ArrayList<HashMap<String,Object>> data = new ArrayList<HashMap<String,Object>>();    
10         HashMap<String,Object> hm = null;       
11         for(int i=0;i<5;i++) {             
12             hm = new HashMap<String,Object>();          
13             hm.put("data", "text1------"+i);        
14             hm.put("image", R.drawable.ic_launcher);       
15             data.add(hm);         
16         }        
17         SimpleAdapter sa = new SimpleAdapter(this, data,R.layout.list_layout, new String[]{"data", "image"}, new int[]{R.id.list_text1, R.id.list_image});          
18         listview.setAdapter(sa);          
19         listview.setOnItemClickListener(new OnItemClickListener() {              
20             @Override             
21             public void onItemClick(AdapterView<?> parent, View view, int position, long id ) {                 
22             // TODO Auto-generated method stub                  
23             Toast.makeText(ListViewTestActivity.this, (String)((HashMap<String, Object>)listview.getItemAtPosition(position)).get("data"), Toast.LENGTH_SHORT).show();              
24           }          
25         });      
26     }    
27 } 
 1 list_layout.xml  
 2 <?xml version="1.0" encoding="utf-8"?> 
 3     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
 4         android:layout_width="match_parent"     
 5         android:layout_height="match_parent"     
 6         android:orientation="horizontal" >      
 7     <ImageView         
 8         android:id="@+id/list_image"         
 9         android:layout_width="wrap_content"      
10         android:layout_height="wrap_content" />  
11     <TextView        
12         android:id="@+id/list_text1"    
13         android:textSize="13pt"        
14         android:layout_width="fill_parent"    
15         android:layout_height="wrap_content" />  
16 </LinearLayout> 

(3)接着说下SimpleCursorAdapter:通过一个游标来控制数据的获取。这里哪一个获取联系人的例子来展示一下!

 1 public class CursorAdapterTestActivity extends Activity {     
 2     public ListView myList;       
 3     /** Called when the activity is first created. */    
 4     @SuppressWarnings("deprecation")      
 5     @Override     
 6     public void onCreate(Bundle savedInstanceState) {         
 7         super.onCreate(savedInstanceState);         
 8         setContentView(R.layout.main);         
 9         myList = (ListView) findViewById(R.id.list);         
10         Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);          
11         startManagingCursor(cursor);          
12         ListAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, 
13             cursor, new String[] { People.NAME }, new int[] { android.R.id.text1 });         
14         myList.setAdapter(adapter);      
15     }  
16 } 

千万别忘了在manifest里加上对联系人的读取权限!

(4)下面来说功能最强的adapter---baseadapter,只有使用baseadapter才能做到listview的优化。
有时候,列表不光会用来做显示用,我们同样可以在在上面添加按钮。添加按钮首先要写一个有按钮的xml文件,然后自然会想到用上面的方法定义一个适配器,然后将数据映射到布局文件上。但是事实并非这样,因为按钮是无法映射的,即使你成功的用布局文件显示出了按钮也无法添加按钮的响应,这时必须要重写一个类继承BaseAdapter。
当系统开始绘制ListView的时候,首先调用getCount()方法。得到它的返回值,即ListView的长度。然后系统调用getView()方法,根据这个长度逐一绘制ListView的每一行。也就是说,如果让getCount()返回1,那么只显示一行。而getItem()和getItemId()则在需要处理和取得Adapter中的数据时调用。那么getView如何使用呢?如果有10000行数据,就绘制10000次?这肯定会极大的消耗资源,导致ListView滑动非常的慢,那应该怎么做呢?通过一个例子来讲解如何在使用BaseAdapter的时候优化ListView的显示。例子中将上一节中的ImageView换成Button,并且处理Button的点击事件,其中对ListView的显示做了优化。

 1 public class ArrayListDemoActivity extends Activity {       
 2     // 定义一个String数组用来显示ListView的内容     
 3     private ListView lv;      
 4     ArrayList<HashMap<String, Object>> listItem;       
 5     /** Called when the activity is first created. */     
 6     @Override     
 7     public void onCreate(Bundle savedInstanceState) {         
 8         super.onCreate(savedInstanceState);         
 9         setContentView(R.layout.main);         
10         listItem = getListDate();          
11         lv = (ListView) findViewById(R.id.mylist);          
12         MyAdapter mAdapter = new MyAdapter(this);// 得到一个MyAdapter对象          
13         lv.setAdapter(mAdapter);// 为ListView绑定Adapter          
14         /* 为ListView添加点击事件 */         
15         lv.setOnItemClickListener(new OnItemClickListener() {            
16             @Override            
17             public void onItemClick(AdapterView<?> arg0, View view, int position, long id) { 
18                 Toast.makeText(ArrayListDemoActivity.this, "你点击了ListView条目" + position, Toast.LENGTH_SHORT).show();             
19             }          
20         });      
21     }       
22     /* 添加一个得到数据的方法,方便使用 */     
23     private ArrayList<HashMap<String, Object>> getListDate() {          
24         ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();          
25         /* 为动态数组添加数据 */        
26         for (int i = 0; i < 50; i++) {            
27             HashMap<String, Object> map = new HashMap<String, Object>(); 
28             map.put("ItemTitle", "第" + i + "行");           
29             map.put("ItemText", "这是第" + i + "行");        
30             listItem.add(map);        
31         }         
32         return listItem;     
33     }       
34     /**       
35      * @author vtianyun       
36      * @date 2012-4-4       
37      * 自定义Adapter的实现       
38      */     
39     private class MyAdapter extends BaseAdapter {         
40         private LayoutInflater mInflater;// 得到一个LayoutInfalter对象用来导入布局           
41         /* 构造方法*/         
42         public MyAdapter(Context context) {              
43             this.mInflater = LayoutInflater.from(context);        
44         }          
45         @Override     
46         public int getCount() {  
47             return listItem.size();// 返回数组的长度       
48         }         
49         @Override   
50         public Object getItem(int position) {     
51             return null;     
52         }           
53         @Override        
54          public long getItemId(int position) {           
55            return 0;          
56            }           
57         @Override         
58         public View getView(final int position, View convertView, ViewGroup parent) {
59             ViewHolder holder;                            
60             // 观察convertView随ListView滚动情况              
61             System.out.println("getView = " + position + ", convertView = " + convertView);                            
62             if (convertView == null) {                  
63                 convertView = mInflater.inflate(R.layout.list, null);                  
64                 holder = new ViewHolder(); // 得到各个控件的对象                  
65                 holder.title = (TextView) convertView.findViewById(R.id.ItemTitle);                  
66                 holder.text = (TextView) convertView.findViewById(R.id.ItemText);                  
67                 holder.bt = (Button) convertView.findViewById(R.id.listBtn);                  
68                 convertView.setTag(holder);// 绑定ViewHolder对象              
69             } else {                 
70                 holder = (ViewHolder) convertView.getTag();// 取出ViewHolder对象           
71             }              
72             // 设置TextView显示的内容,即我们存放在动态数组中的数据
73             holder.title.setText(listItem.get(position).get("ItemTitle").toString());
74             holder.text.setText(listItem.get(position).get("ItemText").toString());              
75             // 为Button添加点击事件              
76             holder.bt.setOnClickListener(new OnClickListener() {                
77                 @Override                 
78                 public void onClick(View v) {                      
79                     Toast.makeText(ArrayListDemoActivity.this, "你点击了按钮" + position, Toast.LENGTH_SHORT).show(); // 打印Button的点击信息    
80                 }              
81             });              
82             return convertView;         
83         }     
84     }      
85     /**       
86     * @author vtianyun       
87     * @date 2012-4-4       
88     * 存放控件,当下次再调用时,不用再去findViewById了,这个比较费时       
89     */     
90     public final class ViewHolder {          
91         public TextView title;          
92         public TextView text;          
93         public Button bt;      
94       }  
95     } 

这里用一个ViewHolder对象来持有这个Layout里的三个组件的对象,这样在滚动listview的时候,就不用再去find了,因为这个操作是很费时的,这样做后,流畅度大大提高,特别是在比较复杂的list里。
还需要注意的是,Button会抢夺ListView的焦点,需要将Button设置为没有焦点。设置非常简单,只需要在xml的Button标签下加入一行:android:focusable=“false”代码就可以了。
这里还用到了一个View.setTag()知识,这表示给view额外的添加一个数据,和原来的view捆绑在一起,等到用的时候可以直接getTag拿出来,网上有个例子教程说的就是给很多button绑上一个整型的tag标记,然后在onClickListener里就可以通过这个tag标记来判断该响应哪个按钮的操作了!
通过查看logcat可以发现,内存被重复使用了,这样既减小了内存开销,在重用的同时,通过getTag获取对象,大大提高了效率!

转载于:https://www.cnblogs.com/vtianyun/archive/2012/04/15/2450991.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值