ListView的高级使用
ListView在android开放中用的比较多,所以接下来就进行ListView的使用的讲解。
首先创建一个android项目,项目名为ListViewTest.
ListView的简单使用
修改布局文件,修改后代码如下:
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <ListView
- android:id="@+id/list_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- ></ListView>
- </LinearLayout>
修改MainActivity的代码:
- package com.wj.listviewtest;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.widget.ArrayAdapter;
- import android.widget.ListView;
- public class MainActivity extends Activity {
- private String [] data={"apple","banana","orange",
- "watermelon","pear","grape","pineapple","strawberry",
- "cherry","mango"};
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //创建适配器
- ArrayAdapter<String> adapter=new ArrayAdapter<String>(
- MainActivity.this,android.R.layout.simple_list_item_1,
- data);
- ListView listView=(ListView) findViewById(R.id.list_view);
- listView.setAdapter(adapter);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- }
运行程序结果如下:
ListView是用于显示大量数据的,这些数据我们可以事先准备好,也可以从网上或者数据中中读取。
android.R.layout.simple_list_item_1是作为ListView子项布局的id,这是android内置的布局文件里面只有一个TextView,可用于简单地显示一段文本。
2.定制ListView的界面
首先准备一组图片,分别对应上面提供的水果。
接着定义一个实体类,作为ListView适配器的适配类型,新建Fruit类,代码如下:
- package com.wj.listviewtest;
- public class Fruit {
- private String name;//水果名
- private int imageId;//水果图片的资源id
- //无参构造函数
- public Fruit(){}
- //有参构造函数
- public Fruit(String name,int imageId){
- this.name=name;
- this.imageId=imageId;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getImageId() {
- return imageId;
- }
- public void setImageId(int imageId) {
- this.imageId = imageId;
- }
- }
Fruit类中只有2个字段,name表示水果的名字,imageId表示水果对应图片的资源id,然后需要为ListView的子项指定一个我们自定义的布局,在layout目录下面新建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"
- >
- <ImageView
- android:id="@+id/fruit_image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- <TextView
- android:id="@+id/fruit_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginLeft="10dip"
- />
- </LinearLayout>
这个布局中我们定义了一个ImageView用于显示水果的图片,又定义了一个TextView用于显示水果的名称。
接着我们要创建一个自定义的适配器,这个适配器继承自ArrayAdapter,并将泛型指定为Fruit。新建一个类FruitAdapter代码如下:
- package com.wj.listviewtest;
- import java.util.List;
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ArrayAdapter;
- import android.widget.ImageView;
- import android.widget.TextView;
- public class FruitAdapter extends ArrayAdapter<Fruit> {
- private int resourceId;
- public FruitAdapter(Context context, int textViewResourceId,
- List<Fruit> objects) {
- super(context, textViewResourceId, objects);
- // TODO Auto-generated constructor stub
- /*
- * 重写了父类的构造函数,用于将上下文,ListView子项布局的id和数据都传进来。
- * */
- resourceId=textViewResourceId;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- //return super.getView(position, convertView, parent);
- /*
- * 重写getView方法,这个方法在每个子项被滚动到屏幕内的时候会被调用,在getView方法中
- * ,首先通过getItem方法得到当前项的Fruit实例,然后使用LayoutInflater来为这个子项加载
- * 我们传入的布局,接着调用View的findViewById方法分别获取到ImageView和TextView的实例,
- * 并分别调用他们的setImageResource和setText方法来设置显示的图片和文字,最后返回布局
- * */
- Fruit fruit=getItem(position);//获取当前项的Fruit实例
- //初始话ListView的子项布局
- View view=LayoutInflater.from(getContext()).inflate(resourceId, null);
- ImageView fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
- TextView fruitName=(TextView) view.findViewById(R.id.fruit_name);
- fruitImage.setImageResource(fruit.getImageId());
- fruitName.setText(fruit.getName());
- return view;
- }
- }
修改MainActivity的代码如下:
- package com.wj.listviewtest;
- import java.util.ArrayList;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.widget.ArrayAdapter;
- import android.widget.ListView;
- public class MainActivity extends Activity {
- /*private String [] data={"apple","banana","orange",
- "watermelon","pear","grape","pineapple","strawberry",
- "cherry","mango"};*/
- private List<Fruit> fruitList=new ArrayList<Fruit>();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- /*//创建适配器
- ArrayAdapter<String> adapter=new ArrayAdapter<String>(
- MainActivity.this,android.R.layout.simple_list_item_1,
- data);
- ListView listView=(ListView) findViewById(R.id.list_view);
- listView.setAdapter(adapter);*/
- initFruits();//初始化水果
- FruitAdapter adapter=new FruitAdapter(MainActivity.this,
- R.layout.fruit_item, fruitList);
- ListView listView=(ListView) findViewById(R.id.list_view);
- //设置适配器
- listView.setAdapter(adapter);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- public void initFruits(){
- Fruit apple=new Fruit("apple",R.drawable.apple_pic);
- fruitList.add(apple);
- Fruit banana=new Fruit("banana",R.drawable.banana_pic);
- fruitList.add(banana);
- Fruit orange=new Fruit("orange",R.drawable.orange_pic);
- fruitList.add(orange);
- Fruit watermelon=new Fruit("watermelon",R.drawable.watermelon_pic);
- fruitList.add(watermelon);
- Fruit pear=new Fruit("pear",R.drawable.pear_pic);
- fruitList.add(pear);
- Fruit grape=new Fruit("grape",R.drawable.grape_pic);
- fruitList.add(grape);
- Fruit pineapple=new Fruit("pineapple",R.drawable.pineapple_pic);
- fruitList.add(pineapple);
- Fruit strawberry=new Fruit("strawberry",R.drawable.strawberry_pic);
- fruitList.add(strawberry);
- Fruit cherry=new Fruit("cherry",R.drawable.cherry_pic);
- fruitList.add(cherry);
- Fruit mango=new Fruit("mango",R.drawable.mango_pic);
- fruitList.add(mango);
- }
- }
运行程序,结果如下:
这是一个简单的界面,不过更加复杂的界面也可以通过修改fruit_item.xml文件来实现更加复杂的ListView。
下面我们来提示下ListView的运行效率。
目前我们的ListView的运行效率是很低的,因为在FruitAdapter的getView方法中每次都要将布局重写加载了一遍,当ListView快速滚动的时候这就会成为性能的瓶颈。仔细观察,getView方法中还有一个convertView参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用,修改FruitAdapter中的代码,带入如下所示:
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- //return super.getView(position, convertView, parent);
- /*
- * 重写getView方法,这个方法在每个子项被滚动到屏幕内的时候会被调用,在getView方法中
- * ,首先通过getItem方法得到当前项的Fruit实例,然后使用LayoutInflater来为这个子项加载
- * 我们传入的布局,接着调用View的findViewById方法分别获取到ImageView和TextView的实例,
- * 并分别调用他们的setImageResource和setText方法来设置显示的图片和文字,最后返回布局
- * */
- Fruit fruit=getItem(position);//获取当前项的Fruit实例
- View view;
- /*
- * 在getView()方法中进行判断,如果convertView为空,则使用LayoutInflater去加载布局,
- * 如果不为空,则直接对convertView进行重用。这样可以大大提升ListView的效率,在快速滚动的时候
- * 也可以表现更好的性能。
- * */
- if(convertView==null){
- //初始话ListView的子项布局
- view=LayoutInflater.from(getContext()).inflate(resourceId, null);
- }else{
- view=convertView;
- }
- /*//初始话ListView的子项布局
- View view=LayoutInflater.from(getContext()).inflate(resourceId, null);*/
- ImageView fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
- TextView fruitName=(TextView) view.findViewById(R.id.fruit_name);
- fruitImage.setImageResource(fruit.getImageId());
- fruitName.setText(fruit.getName());
- return view;
- }
上面的代码进行了部分的优化,虽然现在已经不用在重复的去加载布局了,但是每次在getView方法中还是会调用View的view.findViewById()方法来获取一次控件的实例。我们可以借助一个ViewHolder来对这部分性能进行优化,修改FruitAdapter中的代码,如下所示:
- package com.wj.listviewtest;
- import java.util.List;
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ArrayAdapter;
- import android.widget.ImageView;
- import android.widget.TextView;
- public class FruitAdapter extends ArrayAdapter<Fruit> {
- private int resourceId;
- public FruitAdapter(Context context, int textViewResourceId,
- List<Fruit> objects) {
- super(context, textViewResourceId, objects);
- // TODO Auto-generated constructor stub
- /*
- * 重写了父类的构造函数,用于将上下文,ListView子项布局的id和数据都传进来。
- * */
- resourceId=textViewResourceId;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- //return super.getView(position, convertView, parent);
- /*
- * 重写getView方法,这个方法在每个子项被滚动到屏幕内的时候会被调用,在getView方法中
- * ,首先通过getItem方法得到当前项的Fruit实例,然后使用LayoutInflater来为这个子项加载
- * 我们传入的布局,接着调用View的findViewById方法分别获取到ImageView和TextView的实例,
- * 并分别调用他们的setImageResource和setText方法来设置显示的图片和文字,最后返回布局
- * */
- Fruit fruit=getItem(position);//获取当前项的Fruit实例
- View view;
- ViewHolder viewHolder;
- /*
- * 在getView()方法中进行判断,如果convertView为空,则使用LayoutInflater去加载布局,
- * 如果不为空,则直接对convertView进行重用。这样可以大大提升ListView的效率,在快速滚动的时候
- * 也可以表现更好的性能。
- * */
- if(convertView==null){
- //初始话ListView的子项布局
- view=LayoutInflater.from(getContext()).inflate(resourceId, null);
- viewHolder=new ViewHolder();
- viewHolder.fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
- viewHolder.fruitName=(TextView) view.findViewById(R.id.fruit_name);
- view.setTag(viewHolder);//将ViewHolder存储在View中
- }else{
- view=convertView;
- viewHolder=(ViewHolder) view.getTag();//重新获取ViewHolder
- }
- /*//初始话ListView的子项布局
- View view=LayoutInflater.from(getContext()).inflate(resourceId, null);*/
- /*ImageView fruitImage=(ImageView) view.findViewById(R.id.fruit_image);
- TextView fruitName=(TextView) view.findViewById(R.id.fruit_name);*/
- viewHolder.fruitImage.setImageResource(fruit.getImageId());
- viewHolder.fruitName.setText(fruit.getName());
- return view;
- }
- class ViewHolder{
- ImageView fruitImage;
- TextView fruitName;
- }
- }
通过上面两步优化后,ListView的运行效率已经不错了。
ListView的点击事件
修改代码如下:
- package com.wj.listviewtest;
- import java.util.ArrayList;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.View;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.ArrayAdapter;
- import android.widget.ListView;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- /*private String [] data={"apple","banana","orange",
- "watermelon","pear","grape","pineapple","strawberry",
- "cherry","mango"};*/
- private List<Fruit> fruitList=new ArrayList<Fruit>();
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- /*//创建适配器
- ArrayAdapter<String> adapter=new ArrayAdapter<String>(
- MainActivity.this,android.R.layout.simple_list_item_1,
- data);
- ListView listView=(ListView) findViewById(R.id.list_view);
- listView.setAdapter(adapter);*/
- initFruits();//初始化水果
- FruitAdapter adapter=new FruitAdapter(MainActivity.this,
- R.layout.fruit_item, fruitList);
- ListView listView=(ListView) findViewById(R.id.list_view);
- //设置适配器
- listView.setAdapter(adapter);
- /*
- * setOnItemClickListener()方法来为ListView注册一个监听器,当用户点击了ListView
- * 中的任何一个子项时就会回调nItemClick()方法,在这个方法中可以通过position参数判断出用户点击
- * 的是哪一个子项,然后获取相应的水果,并通过Toast将水果的名字显示出来。
- * */
- listView.setOnItemClickListener(new OnItemClickListener(){
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position,
- long id) {
- // TODO Auto-generated method stub
- Fruit fruit=fruitList.get(position);
- Toast.makeText(MainActivity.this,
- fruit.getName(), Toast.LENGTH_SHORT).show();
- }
- });
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- public void initFruits(){
- Fruit apple=new Fruit("apple",R.drawable.apple_pic);
- fruitList.add(apple);
- Fruit banana=new Fruit("banana",R.drawable.banana_pic);
- fruitList.add(banana);
- Fruit orange=new Fruit("orange",R.drawable.orange_pic);
- fruitList.add(orange);
- Fruit watermelon=new Fruit("watermelon",R.drawable.watermelon_pic);
- fruitList.add(watermelon);
- Fruit pear=new Fruit("pear",R.drawable.pear_pic);
- fruitList.add(pear);
- Fruit grape=new Fruit("grape",R.drawable.grape_pic);
- fruitList.add(grape);
- Fruit pineapple=new Fruit("pineapple",R.drawable.pineapple_pic);
- fruitList.add(pineapple);
- Fruit strawberry=new Fruit("strawberry",R.drawable.strawberry_pic);
- fruitList.add(strawberry);
- Fruit cherry=new Fruit("cherry",R.drawable.cherry_pic);
- fruitList.add(cherry);
- Fruit mango=new Fruit("mango",R.drawable.mango_pic);
- fruitList.add(mango);
- }
- }
- 本文转载自 http://blog.csdn.net/j903829182/article/details/40683293
ListView的高级使用相关推荐
- 【Flutter】ListView 列表高级功能 ( ScrollController 上拉加载更多 )
文章目录 一.ScrollController 上拉加载更多 二.ScrollController 使用流程 三.ScrollController 判定滑动到底部 四.完整代码示例 五.相关资源 一. ...
- 【Flutter】ListView 列表高级功能 ( RefreshIndicator 下拉刷新组件 )
文章目录 一.下拉刷新组件 二.下拉刷新代码示例 三.相关资源 一.下拉刷新组件 使用 Flutter 提供的 RefreshIndicator 组件 , 可以实现下拉刷新的功能 ; 使用 Refre ...
- ListView 和 RecyclerView 的使用
ListView的讲解 ListView详细介绍与使用 前言介绍: 关于 ListView 我们大家都应该是非常的熟悉了,在 Android 开发中是经常用到的,今天就再来回顾一下,ListView ...
- qml的ListView控件添加ScrollBar
下文提供了2种ListView控件和ScrollBar混合使用的方法: QML中ListView的高级使用之增加ScrollBar以及设置ScrollBar的样式_Joven_xxx的博客-CSDN博 ...
- RecycleView简介及基本使用
##RecycleView简介 RecyclerView控件和ListView的原理有很多相似的地方,都是维护少量的View来进行显示大量的数据,不过RecyclerView控件比ListView更加 ...
- Android面试问答
上次更新时间:2019年1月4日 我们的Android面试问答集全部涉及可在面试中使用的不同类型的问题,以便雇主测试您的技能和知识. 在以下各节中,我们将讨论有关Android OS的功能,命令行工具 ...
- RecyclerView完全解析,让你从此爱上它(二十八)
RecyclerView完全解析,让你从此爱上它(二十八) 2015-11-20 0 个评论 来源: 专注移动开发,项目管理.jiangqqlmj 收藏 我要投稿 (一).前言: ...
- Android:RecyclerView简单理解和基本使用
RecyclerView RecyclerView 一.RecyclerView 二.RecyclerView基本介绍: 三.RecyclerView基本实现: 参考 RecyclerView 一.R ...
- RecyclerView 使用 和简单demo
先看一下效果,随便从网上找的数据,首先看一下效果 ,随便从网上找的数据 经过简单配置可实现三种不同的配置 很简单 第一种 水平List 第二种 垂直List 第三种 GridVIew 显示 4 ...
最新文章
- 《大话设计模式》勘误
- 启明云端分享| 在应用启明云端sigmastar SSD201 / SSD202D核心板时,ISP烧录uboot遇到问题怎么解决呢
- VTK:高亮选择动画用法实战
- ubuntu搭建nodejs生产环境——快速部署手册
- php weize_docs.html
- 这就是数据分析之算法认知
- SpringCloud 微服务 (十五) 服务容错 Hystrix
- java传递引用参数
- 关于DYNPRO程序的系统迁移与版本不匹配问题之一
- Atitit. Derby的使用总结attilax
- hutool压缩文件
- slideUp()方法和slideDown()方法
- Ubuntu软件安装卸载
- 《金融科技(FinTech)发展规划(2019-2021年)》梳理
- NeurIPS 2022 | PEMN:参数集约型掩码网络
- 【Ubuntu】远程软件安装与卸载
- 经典加密算法的实现与破解大素数生成算法
- java mongo replica_mongo 的replica set的集群模式 实现读写分离
- MySQL数据库学习(二)
- 31、什么是 BIO?
热门文章
- RDKit:化合物骨架分析
- 基于概率论的生成式建模新模式
- 华为充电器接口叫什么_插座USB接口跟手机充电器有什么不同_电工百科
- Microbiome:Kraken2进行16S物种注释又快又准
- Nature: 人的肠道古细菌基因组集
- 高级转录组调控分析和R语言数据可视化第十三期 (线上线下,7月底开课)
- Microbiome:南土所梁玉婷组-稻田土壤产甲烷菌的共存模式
- Nature灵魂拷问:微生物组数据一大堆,如何能改变人类健康?
- Seaborn可视化使用relplot函数可视化数据长度不同的时间序列实战:two Pandas Series of different lengths
- 数据库中的字段varchar类型和char类型的区别?