<Android基础>(三) UI开发 Part 2 ListView
ListView
1)ListView的简单用法
2)定制ListView界面
3)提升ListView的运行效率
4)ListView的点击事件
3.5 ListView
3.5.1 ListView的简单用法
1.新建项目,修改activity_main.xml中的代码,插入<ListView>控件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"> </ListView>
</LinearLayout>
2.修改MainActivity中的代码
public class MainActivity extends AppCompatActivity {
private String[] data = new String[]{"gareen","teemo","shana","annie",
"gareen","teemo","shana","annie","gareen","teemo","shana","annie","gareen","teemo","shana","annie",
"gareen","teemo","shana","annie",};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity_layout);
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);
}
}
a.提供好数据,用一组字符串数组data来测试。
b.数组中数据无法直接传递给ListView,需要借助适配器来完成。
ArrayAdapter通过泛型来指定要适配的数据类型,然后在构造函数中把要适配的数据传入。
将ArrayAdapter的泛型指定为String,在构造函数中依次上传当前上下文、ListView子项布局的id、以及要适配的数据。
运行程序的结果

3.5.2 定制ListView的界面
对ListView界面进行定制,让显示更丰富的内容,实现让英雄名称旁边都有各自对应的英雄头像
1.准备好一组图片存在drawable-hdpi
2.定义一个实体类,作为ListView适配器的适配类型。新建类Hero
public class Hero {
private String name;
private int imageId;
public Hero(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId(){
return imageId;
}
}
name表示英雄名字,imageId表示对应的图片资源id
3.在layout目录下新建hero_item.xml为ListView指定自定义的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:id="@+id/hero_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> <TextView
android:id="@+id/hero_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="10dp"/> </LinearLayout>
4.创建一个自定义的适配器,继承自ArrayAdapter,并将泛型指向Hero类。
新建类HeroAdapter。
HeroAdapter重写了父类的一组构造方法,用于将上下文,ListView子项布局的id和数据都传递进来。
另外又重写了getView()方法。首先通过getItem()方法得到当前项的Hero实例,然后使用LayoutInflater来为这个子项加载传入的布局。inflate()方法接受3个参数,第三个参数指定成false,表明只让在父布局中声明layout属性生效,但不会为这个View添加父布局。
接下来调用View的findViewById()方法分别获取ImageView和TextView的实例,并分别调用它们的setImageResource()和setText()方法来设置显示的图片和文字,最后将布局返回。
import android.content.Context;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView; import java.util.List; public class HeroAdapter extends ArrayAdapter<Hero> {
private int resourceId; public HeroAdapter(Context context, int textViewResoureced,
List<Hero> objects){
super(context, textViewResoureced, objects);
resourceId = textViewResoureced;
} @NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Hero hero = getItem(position);
View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
ImageView heroImage = (ImageView) view.findViewById(R.id.hero_image);
TextView heroName = (TextView)view.findViewById(R.id.hero_name);
heroImage.setImageResource(hero.getImageId());
heroName.setText(hero.getName());
return view;
}
}
5.修改MainActivity中的代码
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView; import java.util.ArrayList;
import java.util.List; public class MainActivity extends AppCompatActivity {
private List<Hero> heroList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initHeros();
HeroAdapter adapter = new HeroAdapter(MainActivity.this,
R.layout.hero_item,heroList);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
} private void initHeros(){
for(int i = 0 ; i < 2 ; i ++){
Hero gareen = new Hero("gareen",R.drawable.gareen);
heroList.add(gareen);
Hero annie = new Hero("annie",R.drawable.annie);
heroList.add(annie);
Hero teemo = new Hero("teemo",R.drawable.teemo);
heroList.add(teemo);
Hero shana = new Hero("shana",R.drawable.shana);
heroList.add(shana);
}
}
}
initHeros()方法用于初始化所有的英雄数据。
在Hero类的构造函数中将水果的名字和对应的图片id传入,然后把创建好的对象添加到英雄列表中。
接着在onCreat()方法中创建了HeroAdapter对象,并将HeroAdapter作为适配器传递给ListView。
运行程序。

定制界面完成。
3.5.3 提升ListView的运行效率
getView()方法中有一个convertView参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以重用。
1.HeroAdapter的gatView()方法中每次都将布局重新加载一边,当ListView快速滚动时,就有可能成为性能的瓶颈。
修改HeroAdapter中的代码
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Hero hero = getItem(position);
View view;
if(convertView == null){
view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
}else{
view = convertView;
}
ImageView heroImage = (ImageView) view.findViewById(R.id.hero_image);
TextView heroName = (TextView)view.findViewById(R.id.hero_name);
heroImage.setImageResource(hero.getImageId());
heroName.setText(hero.getName());
return view;
}
if(convertView == null){
view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
}else{
view = convertView;
}
表示对convertView进行判断,如果为null,则使用LayoutInflater去加载布局,如果不为null则直接对convertView直接重用。
2. 每次在getView()中会调用View的findViewById()方法来获取一次控件的实例。可以用ViewHolder来对这部分进行优化。
修改HeroAdapter中的代码。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Hero hero = getItem(position);
View view;
ViewHolder viewHolder;
if(convertView == null){
view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
viewHolder = new ViewHolder();
viewHolder.heroImage = (ImageView)view.findViewById(R.id.hero_image);
viewHolder.heroName = (TextView)view.findViewById(R.id.hero_name);
view.setTag(viewHolder);
}else{
view = convertView;
viewHolder = (ViewHolder)view.getTag();//重新获取ViewHolder
}
viewHolder.heroImage.setImageResource(hero.getImageId());
viewHolder.heroName.setText(hero.getName());
return view;
} class ViewHolder{
ImageView heroImage;
TextView heroName;
}
View view;
ViewHolder viewHolder;
if(convertView == null){
view = LayoutInflater.from(getContext()).inflate(resourceId,parent,false);
viewHolder = new ViewHolder();
viewHolder.heroImage = (ImageView)view.findViewById(R.id.hero_image);
viewHolder.heroName = (TextView)view.findViewById(R.id.hero_name);
view.setTag(viewHolder);
}else{
view = convertView;
viewHolder = (ViewHolder)view.getTag();//重新获取ViewHolder
}
viewHolder.heroImage.setImageResource(hero.getImageId());
viewHolder.heroName.setText(hero.getName());
class ViewHolder{
ImageView heroImage;
TextView heroName;
}
提供一个内部类ViewHolder,用于对控件进行缓存。当convertView为null时,创建一个ViewHolder对象,并将控件的实例都存放在ViewHolder中,然后调用setTag()方法,将ViewHolder对象储存在VIew中。当convertView不为null时,则调用View的getTag()方法,把ViewHolder重新取出。
所有控件实例都缓存在VIewHolder中,就没有必要每次通过findViewById()方法来获取控件实例了。
3.5.4 ListView的点击事件
给每一个Item添加Toast,修改MainActivity中的代码。
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Hero hero = heroList.get(position);
Toast.makeText(MainActivity.this, hero.getName(), Toast.LENGTH_SHORT).show();
}
});

用setOnItemClikListener()方法为ListView注册一个监听器,当用户点击了ListView中的任何一个子项时,就会回调onItemClick()方法。在该方法中即可通过position参数判断出用户点击的是哪一个子项,然后获得相应的name,通过Toast展现出来。
<Android基础>(三) UI开发 Part 2 ListView的更多相关文章
- <Android基础>(三) UI开发 Part 3 RecyclerView
RecyclerView 1)RecyclerView的基本用法 2)横向滚动和瀑布流滚动 3)注册点击事件 3.6 强大的滚动控件 RecyclerView ListView缺点: 1.不使用技巧优 ...
- <Android基础>(三) UI开发 Part 1
1.常用控件 1)TextView 2)Button 3)EditText 4)ImageView 5)ProgressBar 6)AlertDialog 7)ProgressDialog 2.四种布 ...
- android 基础项目及开发出现:error opening trace file: No such file or directory错误解决
本身这个错误不影响运行,但是看着烦啊.解决方案几种如下: 1.xml标签不完整或者未关闭,常有的事.Eclipse并不是所有的xml标记都检查,单双标记什么的. 2.有人说,据说是 android a ...
- UI开发模式对比:JSP、Android、Flex
前一篇文章分析了Java平台下不同类型WEB框架对开发模式的影响,多数Java领域的WEB框架都是聚焦于服务端MVC的实现,这些框架对View的支持,通常是基于标准的JSP或类似JSP的模板技术如Fr ...
- Android与Swift iOS开发:语言与框架对比
Swift是现在Apple主推的语言,2014年新推出的语言,比Scala等“新”语言还要年轻10岁.2015年秋已经开源.目前在linux上可用,最近已经支持Android NDK:在树莓派上有Sw ...
- Android UI开发第三十一篇——Android的Holo Theme
好长时间没写Android UI方面的文章了,今天就闲扯一下Android的Holo主题.一直做android开发的可能都知道,Android 系统的UI有过两次大的变化,一次是android 3.0 ...
- 【Android】11.0 UI开发(二)——列表控件ListView的简单实现1
************************ 转载请注明出处:https://www.cnblogs.com/xiaofu007/p/10342462.html ***************** ...
- 【转】Android UI开发第三十一篇——Android的Holo Theme
好长时间没写Android UI方面的文章了,今天就闲扯一下Android的Holo主题.一直做android开发的可能都知道,Android 系统的UI有过两次大的变化,一次是android 3.0 ...
- Android UI开发第三十九篇——Tab界面实现汇总及比较
Tab布局是iOS的经典布局,Android应用中也有大量应用,前面也写过Android中TAb的实现,<Android UI开发第十八篇——ActivityGroup实现tab功能>.这 ...
随机推荐
- 从.Net到Java学习第十一篇——SpringBoot登录实现
从.Net到Java学习系列目录 通过前面10篇文章的学习,相信我们对SpringBoot已经有了一些了解,那么如何来验证我们的学习成果呢?当然是通过做项目来证明啦!所以从这一篇开始我将会对之前自己做 ...
- Android为TV端助力context转换类型
- Linux命令学习总结:ls
命令简介: ls命令用来列出目标目录(缺省的话为当前目录)中所有的子目录和文件.指令英文原义:list 指令所在路径:/bin/ls 执行权限:All User 命令语法: ls [OPTION].. ...
- 宋宝华:关于Ftrace的一个完整案例【转】
Ftrace简介 Ftrace是Linux进行代码级实践分析最有效的工具之一,比如我们进行一个系统调用,出来的时间过长,我们想知道时间花哪里去了,利用Ftrace就可以追踪到一级级的时间分布. Ftr ...
- 【任务】信息检索.MOOC学习
[博客导航] [信息检索导航] 任务 18年12月4日开始,快速浏览,学习中国大学MOOC平台上黄如花老师的<信息检索>课程. 关键动力 0.搜索是最基础的能力,需要系统学习并应用. 1. ...
- vue 应用生产环境的 webpack 打包配置优化
转:https://blog.csdn.net/robin_star_/article/details/83856363 前言:很好的打包优化的帖子,还没来的急去实测验证 1. 去掉 console ...
- Cursor: Pin S Wait On X In The Top 5 Wait Events
Wait Events , Posted in: Technical Track Tags: Group Blog Posts, Oracle, Technical Blog Lately, wait ...
- spring boot 2.0 WebMvcConfigurerAdapter过时解决方法
第一种: @Configuration public class WebAppConfig implements WebMvcConfigurer{ @Bean public HandlerInter ...
- jeecg开发环境搭建
Maven安装 步骤见:https://www.cnblogs.com/dyh004/p/8523260.html 修改Maven仓库 1.修改maven仓库存放位置 修改maven仓库存放位置:找到 ...
- Python之find命令中的位置的算法
find("s",a,b) #s表示的是一个子序列,a表示的是检索的起始位置,b表示的是检索的终止位置,ab可有可无 test = "abcdefgh" ...