第一行代码3.5-最常用和最难用的控件--ListView
2016-02-04 15:31
288 查看
首先这个控件为什么是最常用的呢?因为手机屏幕大小有限,有些东西比如新闻、手机联系人微博等大量数据不可能全部显示出来,需要通过滑动手机屏幕翻阅信息。这种方法用到的控件就是ListView
1、ListView的简单用法
首先创建一个工程名为ListViewTest,然后在activity_main.xml中添加如下代码:
![](http://img.blog.csdn.net/20160204152824173)
然后在MainActivity.java中添加:
![](http://img.blog.csdn.net/20160204152907596)
其中adapter的作用是设置ListView的布局和数据,第一个参数是context,第二个参数是Android自带的布局,第三个参数是数据。如果是微博,那么这个数据就来自网络,通讯录就来自本地。
效果如下:
![](http://img.blog.csdn.net/20160204153237882)
2、定制ListView的界面
之前的界面太单调了,下面介绍怎么显示图片+文字。
首先创建一个水果类,命名为Fruit:
然后创建显示水果类的布局fruit_item.xml:左边水果图片,右边水果名
注意一些宽度和距离的设置。
由于这个布局中显示的内容包括图片和文字,所以需要自定义适配器来显示:
其中getView函数在每一个子项被滚动到屏幕中显示的时候会被调用。在getView 方法中,首先通过getItem()方法得到当前项的Fruit 实例,然后使用LayoutInflater 来为这个子项加载我们传入的布局,接着调用View 的findViewById()方法分别获取到ImageView 和TextView 的实例,并分别调用它们的setImageResource()和setText()方法来设置显示的图片和文字,最后将布局返回,这样我们自定义的适配器就完成了。
最后修改MainActivity的代码:
![](http://img.blog.csdn.net/20160204160351796)
这样水果的数据和界面都加载完成了。效果如下:
![](http://img.blog.csdn.net/20160204203719772)
3、提升ListView运行效率
之前说到ListView难用,原因之一就是有很多地方可以优化,其中一个地方就是修改getView函数:getView每次都会把布局重新加载一遍,所以当ListView快速滚动的时候,性能会产生瓶颈。
getView中还有一个convertView参数,它就是之前加载的布局的缓存,所以可以这样得到view:
这样在快速滚动ListView的时候效率会有所提升。但是还可以优化,因为每次还是要通过findViewById才能获取控件的实例,所以可以用一个ViewHolder来保存控件,如下:
当view是新加载的时候,会把TextView和ImageView赋值给ViewHolder,并且附到View的TAG中,当读取缓存的时候再从View中获取回来。
4、ListView的点击事件
如果ListView没有点击事件,那也是没什么作用的,所以需要设置每一项的点击事件。注意不是OnClickListener,而是OnItemClickListener。
下面说说这四个参数是什么意思(来自20110921 onItemClick监听器四个arg参数):首先AdapterView表示你现在点击的ListView是哪个,通过View可以获取ListView里面某一项的内容(比如可以获取某一个水果的TextView或者ImageView),position表示点击的item在适配器里的位置,id表示点击的item是listview的第几行,在大部分情况下id和position是相同的。
下面验证通过position获取的水果名和通过view获取的是一样的:
下面是自己另外加的内容:设置长按删除点击事件。长按删除包括在list中删除对应水果和更新适配器。
1、ListView的简单用法
首先创建一个工程名为ListViewTest,然后在activity_main.xml中添加如下代码:
然后在MainActivity.java中添加:
其中adapter的作用是设置ListView的布局和数据,第一个参数是context,第二个参数是Android自带的布局,第三个参数是数据。如果是微博,那么这个数据就来自网络,通讯录就来自本地。
效果如下:
2、定制ListView的界面
之前的界面太单调了,下面介绍怎么显示图片+文字。
首先创建一个水果类,命名为Fruit:
package com.example.listviewtest; public class Fruit { private String name; // 水果名 private int imageId; // 水果图片id public Fruit(String name, int imageId) { this.name = name; this.imageId = imageId; } public String getName() { return name; } public int getImageId() { return imageId; } }
然后创建显示水果类的布局fruit_item.xml:左边水果图片,右边水果名
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/imageView"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:id="@+id/textView" android:layout_marginLeft="10dp"/> </LinearLayout>
注意一些宽度和距离的设置。
由于这个布局中显示的内容包括图片和文字,所以需要自定义适配器来显示:
public class FruitAdapter extends ArrayAdapter<Fruit>{ private int resourceId; public FruitAdapter(Context context, int resource, List<Fruit> objects) { super(context, resource, objects); resourceId = resource; } @Override public View getView(int position, View convertView, ViewGroup parent) { Fruit item = getItem(position); View view = LayoutInflater.from(getContext()).inflate(resourceId, null); TextView tv = (TextView) view.findViewById(R.id.textView); ImageView iv = (ImageView) view.findViewById(R.id.imageView); tv.setText(item.getName()); iv.setImageResource(item.getImageId()); return view; } }
其中getView函数在每一个子项被滚动到屏幕中显示的时候会被调用。在getView 方法中,首先通过getItem()方法得到当前项的Fruit 实例,然后使用LayoutInflater 来为这个子项加载我们传入的布局,接着调用View 的findViewById()方法分别获取到ImageView 和TextView 的实例,并分别调用它们的setImageResource()和setText()方法来设置显示的图片和文字,最后将布局返回,这样我们自定义的适配器就完成了。
最后修改MainActivity的代码:
这样水果的数据和界面都加载完成了。效果如下:
3、提升ListView运行效率
之前说到ListView难用,原因之一就是有很多地方可以优化,其中一个地方就是修改getView函数:getView每次都会把布局重新加载一遍,所以当ListView快速滚动的时候,性能会产生瓶颈。
getView中还有一个convertView参数,它就是之前加载的布局的缓存,所以可以这样得到view:
View view; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceId, null); } else view = convertView;
这样在快速滚动ListView的时候效率会有所提升。但是还可以优化,因为每次还是要通过findViewById才能获取控件的实例,所以可以用一个ViewHolder来保存控件,如下:
@Override public View getView(int position, View convertView, ViewGroup parent) { final Fruit item = getItem(position); View view; ViewHolder viewHolder; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(resourceId, null); viewHolder = new ViewHolder(); viewHolder.imageView = (ImageView) view.findViewById(R.id.imageView); viewHolder.textView = (TextView) view.findViewById(R.id.textView); view.setTag(viewHolder); // 将viewHolder存储到View中 } else { view = convertView; viewHolder = (ViewHolder)view.getTag(); // 重新获取ViewHolder } viewHolder.textView.setText(item.getName()); viewHolder.imageView.setImageResource(item.getImageId()); return view; }
当view是新加载的时候,会把TextView和ImageView赋值给ViewHolder,并且附到View的TAG中,当读取缓存的时候再从View中获取回来。
4、ListView的点击事件
如果ListView没有点击事件,那也是没什么作用的,所以需要设置每一项的点击事件。注意不是OnClickListener,而是OnItemClickListener。
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { Fruit fruit = fruitList.get(position); Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show(); } });
下面说说这四个参数是什么意思(来自20110921 onItemClick监听器四个arg参数):首先AdapterView表示你现在点击的ListView是哪个,通过View可以获取ListView里面某一项的内容(比如可以获取某一个水果的TextView或者ImageView),position表示点击的item在适配器里的位置,id表示点击的item是listview的第几行,在大部分情况下id和position是相同的。
下面验证通过position获取的水果名和通过view获取的是一样的:
TextView fruitText = (TextView) view.findViewById(R.id.textView); Toast.makeText(MainActivity.this, fruitText.getText().toString()+" "+fruit.getName(), Toast.LENGTH_SHORT).show(); // 输出两者相同
下面是自己另外加的内容:设置长按删除点击事件。长按删除包括在list中删除对应水果和更新适配器。
listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long id) { fruitList.remove(position); // 删除对应水果 adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList); // 更新适配器 listview.setAdapter(adapter); return true; } });
相关文章推荐
- 用firefox 插件录制脚本转成java后,运行报错
- C语言解释器Java版-4-内存值转化
- 扩展 Yii2 自带的日志组件
- Java基础:三大特性
- 推荐20个最近很流行的优秀PHP框架
- 从头认识Spring-1.15 对SpEl的值的操作(1)-数值运算
- 代码规范
- eclipse设置
- mina学习笔记七:串口编程
- 国外最流行的PHP MVC框架
- Python学习-快速了解python基本特性
- Simple-Java—Collections(一)Java高效计数器
- USACO rect1 离散化
- python UserAgent
- Yii2 如何实现表单事件之 Ajax 提交
- ___87__UseBrush_GDI使用画刷
- eclipse插件Maven添加依赖查询无结果的解决方法(Select Dependency doesn't work)
- C语言——插入排序
- CMake 编程简介
- Java NIO