Android学习之基础知识五—ListView控件(最常用和最难用的控件)
ListView控件允许用户通过上下滑动来将屏幕外的数据拉到屏幕内,把屏幕内的数据拉到屏幕外。
一、ListView的简单用法
第一步:先创建一个ListViewTest项目,在activity_mian.xml文件中添加ListView控件,宽度和高度可以设置为全屏,即在全屏范围内滑动。

第二步:修改MainActivity中的代码

第三步:运行程序,可以实现上下滚动屏幕的效果(点击屏幕滑动或者鼠标滑动)

代码分析:
1、先将一些数据定义在字符串数组中
2、数据是不能直接传递到ListView中的,需要创建适配器来实现将数据传递到ListView中,Android通过了很多适配器这里使用的是:ArrayAdapter.它可以通过泛型来指定要适配的数据类型,然后在构造函数中把要适配的数据传入。ArrayAdapter有多个构造函数的重载,根据实际情况进行选择。这里我们提供的数据是字符串,因此将泛型指定为:String,然后在构造函数中依次传入当前的上下文、ListView子项布局的id、要适配的数据。
注意:ListView子项布局的id这里我们使用的是:android.R.layout.simple_list_item_1,这是一个android内置的布局文件,里面只有一个TextView,可用于简单的显示一段文本。
3、适配器对象构建好了后,需要调用ListView的setAdapter()方法,将构建好的适配器对象传递出去,这样ListView和数据之间的关联就建立完成了。
二、自定义ListView的界面
第一步:创建Fruit实体类,内含两个字段:水果名称、水果图片资源id

第二步:为ListView的子项指定一个我们自定义的布局:fruit_item.xml,ImageView用于指定水果图片,TextView用于指定水果名称。这里LinearLayout是默认的排列方式:horizontal(水平方式)

第三步:自定义适配器,继承ArrayAdapter,泛型指定为Fruit
1、重写父类的一个构造函数,传入三个参数:上下文、ListView子项布局id、数据
2、重写getView()方法,每个子项滚动到屏幕内的时候就会调用该方法,在该方法中
getItem():得到当前滚动到屏幕内的fruit子项的实例
LayoutInflater:为这个fruit子项加载我们传入的布局
inflate()方法传入三个参数:图片资源id、父布局、false参数(false表示只让我们在父布局中声明的layout属性生效,但不为这个View添加父布局,因为一旦View有了父布局之后,它就不能再添加到ListView中了)
setImageResource():为当前水果项设置图片
setText():为当前水果项设置名称

第四步:修改MainActivity活动中的代码
1、initFruits()方法:初始化所有水果数据,在Fruit类的构造函数中将水果的名称和图片id传入,然后将建好的对象添加到水果列表中。(使用for循环添加两次)
2、setAdapter()方法:将自定义适配器FruitAdapter传给ListView
package com.workspace.hh.listviewtest; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView; import java.util.ArrayList;
import java.util.List; public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList=new ArrayList<>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFruits();
FruitAdapter fruitAdapter=new FruitAdapter(MainActivity.this,R.layout.fruit_item,fruitList);
ListView listView=findViewById(R.id.list_view);
listView.setAdapter(fruitAdapter);
} /**
* 初始化水果,添加两次水果
*/
private void initFruits(){
for(int i=0;i<2;i++){
Fruit apple=new Fruit("Apple",R.drawable.apple_image);
fruitList.add(apple);
Fruit banana=new Fruit("Banana",R.drawable.banana_image);
fruitList.add(banana);
Fruit cherry=new Fruit("Cherry",R.drawable.cherry_image);
fruitList.add(cherry);
Fruit grape=new Fruit("Grape",R.drawable.grape_image);
fruitList.add(grape);
Fruit mango=new Fruit("Mango",R.drawable.mango_image);
fruitList.add(mango);
Fruit orange=new Fruit("Orange",R.drawable.orange_image);
fruitList.add(orange);
Fruit pear=new Fruit("Pear",R.drawable.pear_image);
fruitList.add(pear);
Fruit pineapple=new Fruit("Pineapple",R.drawable.pineapple_image);
fruitList.add(pineapple);
Fruit strawberry=new Fruit("Strawberry",R.drawable.strawberry_image);
fruitList.add(strawberry);
Fruit watermelon=new Fruit("Watermelon",R.drawable.watermelon_image);
fruitList.add(watermelon);
}
}
}
第五步:运行程序,滑动屏幕,效果如下

如果想要定制更多的界面,只需要修改fruit_item.xml中的代码就可以了。
三、提升ListView的运行效率
上面的代码在运行时FruitAdapter存在两个缺陷:
1、getView()方法中,滚动数据时,每次都会将布局重新加载一遍,当ListView快速滚动时,就会成为性能的瓶颈。而在getView()方法中,有个convertView参数我们没有使用到,这个参数用于将之前加载好的布局进行缓存,以便之后进行重用。
2、getView()方法中,每次还是会调用View的findViewById()方法来获取一次控件的实例。我们可以通过创建一个ViewHolder内部类来对控件的实例进行缓存。
FruitAdapter中的代码修改如下:

代码分析:
1、在getView()方法中进行了判断:
convertView为null,则使用LayoutInflater去加载布局
convertView不为null,则直接对convertView进行重用,这样就不用每次都要去加载一次布局了,大大提高了ListView的运行效率。
2、创建ViewHolder内部类,用于缓存控件的实例:
convertView为null,创建一个ViewHolder对象,将控件的实例都放在ViewHolder里面,然后调用View的setTag()方法,把ViewHolder对象存储在View中
convertView不为null,调用View的getTag()方法,把ViewHolder重新取出来。这样控件的所有实例都缓存在了ViewHolder里面,就没有必要每次都通过findViewById()方法来获取控件的实例了。
四、ListView的点击事件
第一步:在MainActivity活动添加ListView的监听事件(setOnItemClickListener())

第二步:运行程序,效果如下:每点击一个水果,就会弹出一个对应水果名的提示信息。

代码分析:
setOnItemClickListener()方法:为ListView注册一个监听器
onItemClick()方法:当用户点击了ListView中的任何一个子项时,就会调用该方法。
五、拓展
上面的例子中使用到了许多图片,这些图片是我从网上下载下来的,下载下来的时候,每张图片的大小是不一样的,为了使每张图片在APP中展示出来的效果一样,需要提前对这些图片进行一个处理:
1、在Android项目的res目录下新建一个Directory:drawable-xxhdpi
2、将网上下载的图片放到drawable-xxhdpi这个文件夹下,注意:图片的命名不能出现大写。
3、先保持图片大小不变,正常的运行程序,然后根据手机上显示出来的图片大小,选择其中一张大小合适的图片(或者根据屏幕判断需要多大尺寸的图片),我这里是根据苹果图片的大小。
4、回到drawable-xxhdpi文件夹下,找到刚刚尺寸合适的图片,右击鼠标,选择编辑,点击主页下的“重新调整大小”

5、弹出一个对话框,点击像素,查看水平和垂直的像素,然后把其他所有图片的这两个值都设置成一样的数值,设置的时候不要勾选“保持纵横比”选项。

6、重新运行程序就可以了。
Android学习之基础知识五—ListView控件(最常用和最难用的控件)的更多相关文章
- Android学习之基础知识五—RecyclerView(滚动控件)
RecyclerView可以说是增强版的ListView,不仅具有ListVIew的效果,还弥补许多ListView的不足. 一.RecyclerView的基本用法 与百分比布局类似,Recycler ...
- Android学习之基础知识五—Android常用的七大控件
一.TextView控件:在界面上显示一段文本信息 先看XML代码和执行效果: 代码分析: 1.android:id属性,给当前控件定义了一个唯一的标识符 2.android:layo ...
- Android学习之基础知识五—创建自定义控件
下面是控件和布局的继承关系: 从上面我们看到: 1.所有控件都是直接或间接继承View,所有的布局都是直接或间接继承ViewGroup 2.View是Android中最基本的UI组件,各种组件其实就是 ...
- Android学习之基础知识五—编写聊天界面
第一步:在app/build.grandle添加RecyclerView依赖库 第二步:在activity_main.xml文件中编写主界面:聊天.发送框.发送按钮三个部分 第三步:编写Message ...
- Android学习之基础知识十五 — 最佳UI体验(Material Design实战)
一.前言 长久以来,大多数人都认为Android系统的UI并不美观,至少没有iOS系统的美观.以至于很多IT公司在进行应用界面设计的时候,为了保证双平台的统一性,强制要求Android端的界面风格必须 ...
- Android学习之基础知识十三 — 四大组件之服务详解第一讲
一.服务是什么 服务(Service)是Android中实现程序后台运行的解决方案,它非常适合去执行那些不需要和用户交互而且还要求长期运行的任务.服务的运行不依赖于任何用户界面,即使程序被切换到后台, ...
- Android学习之基础知识十—内容提供器(Content Provider)
一.跨程序共享数据——内容提供器简介 内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能 ...
- Android学习之基础知识十六 — Android开发高级技巧的掌握
一.全局获取Context的技巧 前面我们很多地方都使用到了Context,弹出Toast的时候.启动活动的时候.发送广播的时候.操作数据库的时候.使用通知的时候等等.或许目前来说我们并没有为得不到C ...
- Android学习之基础知识十四 — Android特色开发之基于位置的服务
一.基于位置的服务简介 LBS:基于位置的服务.随着移动互联网的兴起,这个技术在最近的几年里十分火爆.其实它本身并不是什么时髦的技术,主要的工作原理就是利用无线电通讯网络或GPS等定位方式来确定出移动 ...
随机推荐
- HappenBefore
计算机芯片在操作指令的步骤: 1.获取指令 2.指令进行解码 3.去寄存器里取值 4.开始计算结果(操作) 5.将结果写会到寄存器中 执行代码的顺序可能与编写代码不一致,及虚拟机优化代码顺序,则为指令 ...
- 使用jquery获取iframe内的元素属性
当需要获取iframe里的内容时需要有几个前提,否则你是获取不到的: 1:当前页面与iframe的src的页面需要在同一个域名下: 2:必须要等iframe里边的页面加载完成才能获取,否则你要获取的标 ...
- MSCRM中报表开发二:创建基于FetchXML报表
1. 获取FetchXML.因为FetchXML难以撰写,所以我们一般都是使用高级查找来生成FetchXML或者通过其他工具来生成.我这里在商机界面通过高级查找制作了一个新的视图,名称为 商机查询, ...
- Git应用—03分支管理和冲突解决(转载)
Git 分支管理和冲突解决 https://www.cnblogs.com/mengdd/p/3585038.html 创建分支 git branch 没有参数,显示本地版本库中所有的本地分支名称. ...
- Android事件总线(四)源码解析otto
前言 上一篇文章中讲到了otto的用法,这一篇我们来讲一下otto的源码.可能有人觉得otto过时了,但是通过源码我们学习的是高手设计otto时的设计理念,这种设计理念是不过时的. otto各个类的作 ...
- ViewPager防止Fragment销毁以及取消Fragment的预加载
存在的问题 1. 默认情况下,ViewPager会根据setOffscreenPageLimit()方法设置的大小,自动预加载2. 还是根据setOffscreenPageLimit()方法设置的大小 ...
- Fiddler抓包学习——https请求的抓取
第一步:设置Fiddler windows下安装证书 打开fiddler 查看证书是否安装 说明已安装成功 设置端口号(下面手机设置代理所需要的) 第二部 手机端安装证书 通过fiddler查看电 ...
- 【redis专题(3)】命令语法介绍之link
通过链表结构可以模仿队列结构与堆栈结构:关于队列结构和堆栈结构可以查看https://www.zybuluo.com/a5635268/note/290475 增 lpush key value1 v ...
- iOS-省市区选择的实现
一.简介 该文主要实现的是省市区的选择,可在个人修改地址的地方使用. 二.需要的东西 制作这个首先需要一个area.plist文件,该文件中保存这所有的关于省市区的信息,下载地址:http://pan ...
- python基础 - 元组操作
元组 tuple 元组是不可变对象. 元组初始化 t = tuple() t = () t = tuple(range(1,7,2)) t = (1,2,3,4,5,1) t = (1,) t = ( ...