[转]android ListView详解

本文转自:http://www.cnblogs.com/allin/archive/2010/05/11/1732200.html

由于google doc 很多人都打不开,故更新了源码下载地址 【源码下载】----2011-01-18

  在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。抽空把对ListView的使用做了整理,并写了个小例子,如下图。

 列表的显示需要三个元素:

1.ListVeiw 用来展示列表的View。

2.适配器 用来把数据映射到ListView上的中介。

3.数据    具体的将被映射的字符串,图片,或者基本组件。

根据列表的适配器类型,列表分为三种,ArrayAdapter,SimpleAdapter和SimpleCursorAdapter

其中以ArrayAdapter最为简单,只能展示一行字。SimpleAdapter有最好的扩充性,可以自定义出各种效果。SimpleCursorAdapter可以认为是SimpleAdapter对数据库的简单结合,可以方面的把数据库的内容以列表的形式展示出来。

 我们从最简单的ListView开始:

view sourceprint?
01/**
02 * @author allin
03 *
04 */
05public class MyListView extends Activity {
06  
07    private ListView listView;
08    //private List<String> data = new ArrayList<String>();
09    @Override
10    public void onCreate(Bundle savedInstanceState){
11        super.onCreate(savedInstanceState);
12          
13        listView = new ListView(this);
14        listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData()));
15        setContentView(listView);
16    }
17      
18      
19      
20    private List<String> getData(){
21          
22        List<String> data = new ArrayList<String>();
23        data.add("测试数据1");
24        data.add("测试数据2");
25        data.add("测试数据3");
26        data.add("测试数据4");
27          
28        return data;
29    }
30}

上面代码使用了ArrayAdapter(Context context, int textViewResourceId, List<T> objects)来装配数据,要装配这些数据就需要一个连接ListView视图对象和数组数据的适配器来两者的适配工作,ArrayAdapter的构造需要三个参数,依次为this,布局文件(注意这里的布局文件描述的是列表的每一行的布局,android.R.layout.simple_list_item_1是系统定义好的布局文件只显示一行文字,数据源(一个List集合)。同时用setAdapter()完成适配的最后工作。运行后的现实结构如下图:

SimpleCursorAdapter

  sdk的解释是这样的:An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file. You can specify which columns you want, which views you want to display the columns, and the XML file that defines the appearance of these views。简单的说就是方便把从游标得到的数据进行列表显示,并可以把指定的列映射到对应的TextView中。

  下面的程序是从电话簿中把联系人显示到类表中。先在通讯录中添加一个联系人作为数据库的数据。然后获得一个指向数据库的Cursor并且定义一个布局文件(当然也可以使用系统自带的)。

view sourceprint?
01/**
02 * @author allin
03 *
04 */
05public class MyListView2 extends Activity {
06  
07    private ListView listView;
08    //private List<String> data = new ArrayList<String>();
09    @Override
10    public void onCreate(Bundle savedInstanceState){
11        super.onCreate(savedInstanceState);
12          
13        listView = new ListView(this);
14          
15        Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
16        startManagingCursor(cursor);
17          
18        ListAdapter listAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_expandable_list_item_1, 
19                cursor,
20                new String[]{People.NAME}, 
21                new int[]{android.R.id.text1});
22          
23        listView.setAdapter(listAdapter);
24        setContentView(listView);
25    }
26      
27      
28}

 Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);先获得一个指向系统通讯录数据库的Cursor对象获得数据来源。

 startManagingCursor(cursor);我们将获得的Cursor对象交由Activity管理,这样Cursor的生命周期和Activity便能够自动同步,省去自己手动管理Cursor。

 SimpleCursorAdapter 构造函数前面3个参数和ArrayAdapter是一样的,最后两个参数:一个包含数据库的列的String型数组,一个包含布局文件中对应组件id的int型数组。其作用是自动的将String型数组所表示的每一列数据映射到布局文件对应id的组件上。上面的代码,将NAME列的数据一次映射到布局文件的id为text1的组件上。

注意:需要在AndroidManifest.xml中如权限:<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>

运行后效果如下图:

SimpleAdapter

simpleAdapter的扩展性最好,可以定义各种各样的布局出来,可以放上ImageView(图片),还可以放上Button(按钮),CheckBox(复选框)等等。下面的代码都直接继承了ListActivity,ListActivity和普通的Activity没有太大的差别,不同就是对显示ListView做了许多优化,方面显示而已。

下面的程序是实现一个带有图片的类表。

首先需要定义好一个用来显示每一个列内容的xml

vlist.xml

view sourceprint?
01<?xml version="1.0" encoding="utf-8"?>
02<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03    android:orientation="horizontal" android:layout_width="fill_parent"
04    android:layout_height="fill_parent">
05  
06  
07    <ImageView android:id="@+id/img" 
08        android:layout_width="wrap_content"
09        android:layout_height="wrap_content" 
10        android:layout_margin="5px"/>
11  
12    <LinearLayout android:orientation="vertical"
13        android:layout_width="wrap_content" 
14        android:layout_height="wrap_content">
15  
16        <TextView android:id="@+id/title" 
17            android:layout_width="wrap_content"
18            android:layout_height="wrap_content" 
19            android:textColor="#FFFFFFFF"
20            android:textSize="22px" />
21        <TextView android:id="@+id/info" 
22            android:layout_width="wrap_content"
23            android:layout_height="wrap_content" 
24            android:textColor="#FFFFFFFF"
25            android:textSize="13px" />
26  
27    </LinearLayout>
28  
29  
30</LinearLayout>

下面是实现代码:

view sourceprint?
01/**
02 * @author allin
03 
04 */
05public class MyListView3 extends ListActivity {
06  
07  
08    // private List<String> data = new ArrayList<String>();
09    @Override
10    public void onCreate(Bundle savedInstanceState) {
11        super.onCreate(savedInstanceState);
12  
13        SimpleAdapter adapter = new SimpleAdapter(this,getData(),R.layout.vlist,
14                new String[]{"title","info","img"},
15                new int[]{R.id.title,R.id.info,R.id.img});
16        setListAdapter(adapter);
17    }
18  
19    private List<Map<String, Object>> getData() {
20        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
21  
22        Map<String, Object> map = new HashMap<String, Object>();
23        map.put("title", "G1");
24        map.put("info", "google 1");
25        map.put("img", R.drawable.i1);
26        list.add(map);
27  
28        map = new HashMap<String, Object>();
29        map.put("title", "G2");
30        map.put("info", "google 2");
31        map.put("img", R.drawable.i2);
32        list.add(map);
33  
34        map = new HashMap<String, Object>();
35        map.put("title", "G3");
36        map.put("info", "google 3");
37        map.put("img", R.drawable.i3);
38        list.add(map);
39          
40        return list;
41    }
42}

使用simpleAdapter的数据用一般都是HashMap构成的List,list的每一节对应ListView的每一行。HashMap的每个键值数据映射到布局文件中对应id的组件上。因为系统没有对应的布局文件可用,我们可以自己定义一个布局vlist.xml。下面做适配,new一个SimpleAdapter参数一次是:this,布局文件(vlist.xml),HashMap的 title 和 info,img。布局文件的组件id,title,info,img。布局文件的各组件分别映射到HashMap的各元素上,完成适配。

运行效果如下图:

有按钮的ListView

但是有时候,列表不光会用来做显示用,我们同样可以在在上面添加按钮。添加按钮首先要写一个有按钮的xml文件,然后自然会想到用上面的方法定义一个适配器,然后将数据映射到布局文件上。但是事实并非这样,因为按钮是无法映射的,即使你成功的用布局文件显示出了按钮也无法添加按钮的响应,这时就要研究一下ListView是如何现实的了,而且必须要重写一个类继承BaseAdapter。下面的示例将显示一个按钮和一个图片,两行字如果单击按钮将删除此按钮的所在行。并告诉你ListView究竟是如何工作的。效果如下:

vlist2.xml

view sourceprint?
01<?xml version="1.0" encoding="utf-8"?>
02<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
03    android:orientation="horizontal" 
04    android:layout_width="fill_parent"
05    android:layout_height="fill_parent">
06  
07  
08    <ImageView android:id="@+id/img" 
09        android:layout_width="wrap_content"
10        android:layout_height="wrap_content" 
11        android:layout_margin="5px"/>
12  
13    <LinearLayout android:orientation="vertical"
14        android:layout_width="wrap_content" 
15        android:layout_height="wrap_content">
16  
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" />
27  
28    </LinearLayout>
29  
30  
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" />
36</LinearLayout>

程序代码:

view sourceprint?
001/**
002 * @author allin
003 
004 */
005public class MyListView4 extends ListActivity {
006  
007  
008    private List<Map<String, Object>> mData;
009      
010    @Override
011    public void onCreate(Bundle savedInstanceState) {
012        super.onCreate(savedInstanceState);
013        mData = getData();
014        MyAdapter adapter = new MyAdapter(this);
015        setListAdapter(adapter);
016    }
017  
018    private List<Map<String, Object>> getData() {
019        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
020  
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);
025        list.add(map);
026  
027        map = new HashMap<String, Object>();
028        map.put("title", "G2");
029        map.put("info", "google 2");
030        map.put("img", R.drawable.i2);
031        list.add(map);
032  
033        map = new HashMap<String, Object>();
034        map.put("title", "G3");
035        map.put("info", "google 3");
036        map.put("img", R.drawable.i3);
037        list.add(map);
038          
039        return list;
040    }
041      
042    // ListView 中某项被选中后的逻辑
043    @Override
044    protected void onListItemClick(ListView l, View v, int position, long id) {
045          
046        Log.v("MyListView4-click", (String)mData.get(position).get("title"));
047    }
048      
049    /**
050     * listview中点击按键弹出对话框
051     */
052    public void showInfo(){
053        new AlertDialog.Builder(this)
054        .setTitle("我的listview")
055        .setMessage("介绍...")
056        .setPositiveButton("确定", new DialogInterface.OnClickListener() {
057            @Override
058            public void onClick(DialogInterface dialog, int which) {
059            }
060        })
061        .show();
062          
063    }
064      
065      
066      
067    public final class ViewHolder{
068        public ImageView img;
069        public TextView title;
070        public TextView info;
071        public Button viewBtn;
072    }
073      
074      
075    public class MyAdapter extends BaseAdapter{
076  
077        private LayoutInflater mInflater;
078          
079          
080        public MyAdapter(Context context){
081            this.mInflater = LayoutInflater.from(context);
082        }
083        @Override
084        public int getCount() {
085            // TODO Auto-generated method stub
086            return mData.size();
087        }
088  
089        @Override
090        public Object getItem(int arg0) {
091            // TODO Auto-generated method stub
092            return null;
093        }
094  
095        @Override
096        public long getItemId(int arg0) {
097            // TODO Auto-generated method stub
098            return 0;
099        }
100  
101        @Override
102        public View getView(int position, View convertView, ViewGroup parent) {
103              
104            ViewHolder holder = null;
105            if (convertView == null) {
106                  
107                holder=new ViewHolder();  
108                  
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);
115                  
116            }else {
117                  
118                holder = (ViewHolder)convertView.getTag();
119            }
120              
121              
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"));
125              
126            holder.viewBtn.setOnClickListener(new View.OnClickListener() {
127                  
128                @Override
129                public void onClick(View v) {
130                    showInfo();                 
131                }
132            });
133              
134              
135            return convertView;
136        }
137          
138    }
139      
140      
141      
142      
143}

  下面将对上述代码,做详细的解释,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://www.cnblogs.com/freeliver54/archive/2011/11/03/2234628.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361905.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JBoss BPM Suite 6.0.3版本的5个实用技巧

上周&#xff0c;红帽发布了标记为6.0.3的JBoss BPM Suite的下一版本&#xff0c;已订阅的用户可以在其客户门户中使用。 如果您对该版本的新增功能感到好奇&#xff0c;请在客户门户网站上在线查看版本说明和其余文档 。 我们正在寻找一些简单的方法来开始使用此新版本&…

Django学习---原生ajax

Ajax 原生ajax Ajax主要就是使用 【XmlHttpRequest】对象来完成请求的操作&#xff0c;该对象在主流浏览器中均存在(除早起的IE)&#xff0c;Ajax首次出现IE5.5中存在&#xff08;ActiveX控件&#xff09;。 XmlHttpRequest对象的主要方法&#xff1a; a. void open(String …

霸主–统治和管理API的地方

今天我们生活在一个越来越分散的世界中。 如今的计算机系统不再是在随机桌子下面的某些硬件上运行单个部门项目&#xff0c;而是大规模&#xff0c;集中甚至分散地运行。 监视和管理的需求从未改变&#xff0c;但是随着时间的推移变得越来越复杂。 如果将所有这些跨功能功能都放…

Java开发人员应该知道的5种错误跟踪工具

随着Java生态系统的不断发展&#xff0c;可满足不断增长的请求和用户对高性能需求的Web应用程序成为了新型的现代开发工具。 具有快速新部署的快速节奏环境需要跟踪错误并获得应用程序行为的洞察力&#xff0c;而传统方法无法维持这种水平。 在这篇文章中&#xff0c;我们决定收…

Emacs中的Color Theme以及字体设置

先上一张效果图&#xff1a; Color Theme用的是gnome2, 字体用的是Visual Studio自带的Consolas。我使用的环境是WindowsCygwinEmacs23.2。 1,安装Color Theme插件 首先&#xff0c;从http://download.savannah.gnu.org/releases/color-theme/下载color theme 6.6.0版本。 接着…

vue兼容ie10问题并且node——module中出现es6语法如何解决

一、首先进行安装babel-polyfill&#xff0c;如果你用yarn安装babel-polyfill的话需要yarn add babel-polyfill进行安装 二、在babel.config.js中加入 三、在ie浏览器中找到报错的文件&#xff0c;然后将文件加入其中 转载于:https://www.cnblogs.com/changhuanran/p/11193149.…

2个在Java中将Byte []数组转换为String的示例

将字节数组转换为String似乎很容易&#xff0c;但是很难做到正确。 每当字节转换为String或char时&#xff0c;许多程序员都会犯忽略字符编码的错误&#xff0c;反之亦然。 作为程序员&#xff0c;我们都知道计算机只能理解二进制数据&#xff0c;即0和1。我们看到和使用的所有…

Linux文件IO-例会笔记总结

上周日实验室例会主要涉及linux文件操作的内核实现。主要讨论了linux下对文件进行操作时&#xff0c;系统内部调用了那些函数以及它们是怎么相互配合的。 linux系统是怎样对不同介质和不同的文件系统提供统一的文件操作接口呢&#xff1f;答案是&#xff1a;VFS。系统中所有文件…

用js来实现那些数据结构12(散列表)

上一篇写了如何实现简单的Map结构&#xff0c;因为东西太少了不让上首页。好吧。。。 这一篇文章说一下散列表hashMap的实现。那么为什么要使用hashMap&#xff1f;hashMap又有什么优势呢&#xff1f;hashMap是如何检索数据的&#xff1f;我们一点一点的来解答。 在我们学习一门…

探索SwitchYard 2.0.0.Alpha2快速入门

在我的最后一篇文章中&#xff0c;我解释了如何在WildFly 8.1上使用SwitchYard。 同时&#xff0c;该项目很忙&#xff0c;并发布了另一个Alpha2。 这是一个很好的机会&#xff0c;在这里浏览快速入门并刷新您的记忆。 除了版本更改之外&#xff0c;您仍然可以使用较早的博客来…

走进webpack(1)--环境拆分及模块化

初级的文章和demo已经基本完成了&#xff0c;代码也已经上传到了我的github上&#xff0c;如果你对webpack的使用并不是十分了解&#xff0c;那么建议你回头看下走近系列&#xff0c;里面包括了当前项目中使用频繁的插件&#xff0c;loader的讲解。以及基本的webpack配置&#…

适用于微服务架构的Apache Camel

在知道微服务架构被称为之前&#xff0c;我一直在使用它们。 我曾经使用过由隔离模块组成的管道应用程序&#xff0c;这些模块通过队列相互交互。 从那时起&#xff0c;许多&#xff08;前&#xff09;ThoughtWorks专家讨论了微服务。 首先是 Fred George&#xff0c; 然后是 J…

QueryString加密

有些人不想由URL暴露一些訊息&#xff0c;除了可以使用URL Rewrite之外&#xff0c;其實簡便一點的方法還有使用編碼or加密來達到偽裝的目的。使用Base64的原因是因為他的編碼不會有難以接受的特殊字元(註1)&#xff0c;你也可以用其他的編碼or加密算法替代(註2)。其實這邊已經…

即时大数据流处理=即时风暴

在Ubuntu背后的公司Canonical&#xff0c;每6个月进行一次技术工作&#xff0c;以第一手测试我们的工具并向其他人展示新想法。 这次&#xff0c;我创建了一个即时大数据解决方案&#xff0c;更具体地讲是“即时风暴”。 Storm现在是Apache基金会的一部分&#xff0c;但以前St…

webstorm中vue项目--运行配制

## npm搭建的项目&#xff0c;需要运行npm run dev来启动 webstorm作为一款优秀的编辑器&#xff0c;通过配置运行设置&#xff0c;达到一键运行 1.添加node.js配置 2.configuration->node interpreter : 路径/node.exe 3.configuration->working directory&#xff1a; …

VS2010 自动化整理代码(1)--- VS正则表达替换 PK Vim

自从开始在VS2010的IDE中开始用正则表达式修改 最近为了给Fortran找个好一点的编辑器&#xff0c;又开始使用Vim了。Vim是久负盛名的编辑器之神&#xff0c;可我们习惯了Visual Studio的智能提示等方便的操作&#xff0c;就总在琢磨要是VS 1. VS正则表达替换 PK Vim 这是善用…

2019.7.16考试总结

对于这个狗屎成绩我不想说什么&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;前两次考炸也就算了&#xff0c;主要因为不会&#xff0c;这次考成这狗屎&#xff0c;是因为手残眼瘸大脑间歇性抽搐 T1&#xff1a;我是菜鸡&#xff0c;我是蒟蒻&#xff0c;我好菜…

PrimeFaces Extensions中的全新JSF组件

PrimeFaces扩展团队很高兴宣布即将推出的3.0.0主要版本的几个新组件。 我们的新提交人Francesco Strazzullo为该项目提供了“ Turbo Boost”&#xff0c;并带来了至少6个已成功集成的 JSF组件&#xff01; 当前的开发状态是OpenShift上的deployet – 请查看展示柜。以下是有关添…

15 个最新的 CSS3 教程

1. 创建一个漂亮的图标 这个教程将教你如何用纯CSS3创建一个图中的图标2. CSS3 图片样式 这个教程将教你如何使用 box-shadow, border-radius和transition。3. CSS3 Transition 的模糊效果4. 实用的CSS3圆角表格5. 创建纯CSS3的票式标签6. 原始的鼠标浮动效果 这个教程将创建缩…

C++内存管理——指针数组

C/C程序中&#xff0c;指针和数组在不少地方可以相互替换着用&#xff0c;让人产生一种错觉&#xff0c;以为两者是等价的。但二者有着本质的区别&#xff1a;数组&#xff1a;要么在静态存储区被创建(如全局数组)&#xff0c;要么在栈上被创建。数组名对应着&#xff08;而不是…