zoukankan      html  css  js  c++  java
  • android listview的用法

    原文地址:http://jeyechao.iteye.com/blog/1149127

    Android中ListView这个组件比较常用,但对初学者来说,又比较难掌握,在此分享一下我的使用经验。 ListView是以列表的形式展示数据,这里面有三个要素:数据、视图、适配器。 常用的适配器有三种:ArrayAdapter, SimpleAdapter, SimpleCursorAdapter。 其中SimpleAdapter扩展性最好,几乎能实现所有展示需求的列表,我在实际开发中用的全是这个,这里也只介绍这个。

    假设要实现如下效果的列表视图:

    下面一步步来实现。

    首先设计视图,主要设计ListView里面item的显示效果,在layout中创建item.xml文件,如下:

    Xml代码  收藏代码
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent" android:layout_height="75dp"  
    4.     android:paddingLeft="10dp" android:paddingRight="10dp">  
    5.     <ImageView  
    6.         android:id="@+id/img"  
    7.         android:layout_height="fill_parent"  
    8.         android:layout_width="60dp"  
    9.         android:layout_alignParentLeft="true" />  
    10.     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    11.         android:orientation="vertical" android:layout_height="fill_parent"  
    12.         android:layout_width="fill_parent" android:layout_toRightOf="@id/img"  
    13.         android:paddingLeft="8dp">  
    14.         <TextView  
    15.             android:id="@+id/title1"  
    16.             android:layout_width="wrap_content"  
    17.             android:layout_height="wrap_content"  
    18.             android:textColor="#cbcaca"  
    19.             android:textSize="20dp" />  
    20.         <TextView  
    21.             android:id="@+id/title2"  
    22.             android:layout_width="wrap_content"  
    23.             android:layout_height="wrap_content"  
    24.             android:textColor="#cbcaca"  
    25.             android:textSize="14dp" />  
    26.         <TextView  
    27.             android:id="@+id/time"  
    28.             android:layout_width="wrap_content"  
    29.             android:layout_height="wrap_content"  
    30.             android:textColor="#cbcaca"  
    31.             android:textSize="12dp" />  
    32.     </LinearLayout>  
    33.     <CheckBox  
    34.         android:id="@+id/checked"  
    35.         android:layout_height="fill_parent"  
    36.         android:layout_width="wrap_content"  
    37.         android:layout_alignParentRight="true"  
    38.         android:checked="false"  
    39.         android:focusable="false" />  
    40. </RelativeLayout>  

    此xml文件定义列表中每个项目的布局,如果想要不同的布局,修改此文件的布局即可。

    这个文件中给每个需要在程序中动态赋值的地方都取了id,看到后面的代码时,注意对应关系。

     

    然后是适配器和数据,这两个联系比较紧密,就放一起了。

    先上代码:

    Java代码  收藏代码
    1. //获取ListView对象  
    2. ListView mListView = (ListView)findViewById(R.id.listview);  
    3. //下面是数据映射关系,mFrom和mTo按顺序一一对应  
    4. String[] mFrom = new String[]{"img","title1","title2","time"};  
    5. int[] mTo = new int[]{R.id.img,R.id.title1,R.id.title2,R.id.time};  
    6. //获取数据,这里随便加了10条数据,实际开发中可能需要从数据库或网络读取  
    7. List<Map<String,Object>> mList = new ArrayList<Map<String,Object>>();  
    8. Map<String,Object> mMap = null;  
    9. for(int i = 0;i < 10;i++){  
    10.     mMap = new HashMap<String,Object>();  
    11.     mMap.put("img", R.drawable.icon);  
    12.     mMap.put("title1""标题");  
    13.     mMap.put("title2""副标题");  
    14.     mMap.put("time""2011-08-15 09:00");  
    15.     mList.add(mMap);  
    16. }  
    17. //创建适配器  
    18. SimpleAdapter mAdapter = new SimpleAdapter(this,mList,R.layout.item,mFrom,mTo);  
    19. mListView.setAdapter(mAdapter);  

    这里要注意对应关系,Layout中的id,程序中对它的引用,Map中的数据。 

    到这里已经实现了上面那张图的效果。但是程序需要一些交互操作,比如单击某一项,长按某一项,怎么办?

    看下面:

    添加点击事件:

    Java代码  收藏代码
    1. mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {  
    2.     @Override  
    3.     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
    4.         @SuppressWarnings("unchecked")  
    5.         //获取被点击的item所对应的数据  
    6.         HashMap<String,Object> map = (HashMap<String, Object>) parent.getItemAtPosition(position);  
    7.         //下面是你的其他事务逻辑  
    8.     }  
    9. });  

    这里可以通过position获取被点击的item所对应的Map数据,拿到这个数据了,还怕有什么功能实现不了吗?

    举个最常见的例子,数据是从数据库里取的,每条数据有唯一的id,点了某一项之后,需要得到这个id进行数据操作,怎么办?很简单,在准备数据的时候,往Map中多添加一条数据,map.put("id",id),在上面的事件处理中,可以通过(Long) map.get("id")来获取id(此处假设id是long类型),取到id之后就可以进行数据库操作了。放心,添加的额外数据不会影响View的显示,因为有对应关系在。

    长按事件和这个类似,无非是注册OnItemLongClickListener事件,在此就不列代码了。

    还有最后一个问题,界面中每个item后面显示了一个单选框,明显是为批处理留的,该如何实现呢?

    仔细想一下,会发现难点在于单选框状态的记录及获取。下面是我的方法:

    在定义SimpleAdapter对象的时候,重写它的getView方法。如下:

    Java代码  收藏代码
    1. mAdapter = new SimpleAdapter(this, pictureList, R.layout.picturelist, mFrom, mTo){  
    2.     @Override    
    3.     public View getView(final int position, View convertView, ViewGroup parent) {  
    4.         View view = super.getView(position, convertView, parent);  
    5.         @SuppressWarnings("unchecked")  
    6.         final HashMap<String,Object> map = (HashMap<String, Object>) this.getItem(position);  
    7.         //获取相应View中的Checkbox对象  
    8.         CheckBox checkBox = (CheckBox)view.findViewById(R.id.checked);  
    9.         checkBox.setChecked((Boolean) map.get("checked"));  
    10.         //添加单击事件,在map中记录状态  
    11.         checkBox.setOnClickListener(new View.OnClickListener() {  
    12.             @Override  
    13.             public void onClick(View view) {  
    14.                 map.put("checked", ((CheckBox)view).isChecked());  
    15.             }  
    16.         });  
    17.         return view;  
    18.     }  
    19. };  

    在其他地方获取状态并处理:

    Java代码  收藏代码
    1. //获取列表中的项目总数  
    2. int count = pictureListView.getCount();  
    3. Map<String,Object> map = null;  
    4. boolean isChecked;  
    5. long id;  
    6. for(int i = 0;i < count;i++){  
    7.     map = (Map<String, Object>) pictureListView.getItemAtPosition(i);  
    8.     isChecked = (Boolean) map.get("isChecked");  
    9.     if(isChecked){  
    10.         id = (Long) map.get("id");  
    11.         //被选中的逻辑  
    12.     }  
    13.     else{  
    14.         id = (Long) map.get("id");  
    15.         //未被选中的逻辑  
    16.     }  
    17. }  
    18. //如果操作过程中对列表内容进行了添加或删除,需要调用下面这个方法来更新视图  
    19. mAdapter.notifyDataSetChanged();  

    还有一点忘了写了,demo中的图片是drawable里面的图片,如果map中只有图片的地址,如何把它转成drawable对象显示出来呢?我在这里也研究了好久,map中放入drawable对象传过去好像没用,不会显示,怎么办?好在前面有重写SimpleAdapter的getView方法。map中把图片地址放进去,在getView方法里面,把此地址转成drawable对象,然后设置给ImageView,大功告成!代码如下:

    Java代码  收藏代码
    1. mAdapter = new SimpleAdapter(this, pictureList, R.layout.picturelist, mFrom, mTo){  
    2.     @Override    
    3.     public View getView(final int position, View convertView, ViewGroup parent) {  
    4.         View view = super.getView(position, convertView, parent);  
    5.         @SuppressWarnings("unchecked")  
    6.         final HashMap<String,Object> map = (HashMap<String, Object>) this.getItem(position);  
    7.         ImageView imageView = (ImageView)view.findViewById(R.id.img);  
    8.         FileInputStream fin;  
    9.         try {  
    10.             if(map.get("img") == null){  
    11.                 throw new IOException();  
    12.             }  
    13.             fin = getApplicationContext().openFileInput((String) map.get("img"));  
    14.             imageView.setImageDrawable(Drawable.createFromStream(fin, "src"));  
    15.             fin.close();  
    16.         } catch (FileNotFoundException e) {  
    17.             imageView.setImageResource(R.drawable.default);  
    18.         } catch (IOException e) {  
    19.             imageView.setImageResource(R.drawable.default);  
    20.         }  
    21.         return view;  
    22.     }  
    23. };  

     好了,就到这里了。

  • 相关阅读:
    session笔记-韩顺平
    带宽
    cookie-韩顺平
    分层模式开发+MVC模式开发--韩顺平雇员数据库管理
    韩顺平-雇员管理系统-学习小结
    常用的PHP数据库操作方法(MYSQL版)
    使用Three.js 基本组件以及流程
    three.js 相机
    多线程的操作与数据绑定
    矩阵-
  • 原文地址:https://www.cnblogs.com/s-hk/p/3456061.html
Copyright © 2011-2022 走看看