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的更多相关文章

  1. <Android基础>(三) UI开发 Part 3 RecyclerView

    RecyclerView 1)RecyclerView的基本用法 2)横向滚动和瀑布流滚动 3)注册点击事件 3.6 强大的滚动控件 RecyclerView ListView缺点: 1.不使用技巧优 ...

  2. <Android基础>(三) UI开发 Part 1

    1.常用控件 1)TextView 2)Button 3)EditText 4)ImageView 5)ProgressBar 6)AlertDialog 7)ProgressDialog 2.四种布 ...

  3. android 基础项目及开发出现:error opening trace file: No such file or directory错误解决

    本身这个错误不影响运行,但是看着烦啊.解决方案几种如下: 1.xml标签不完整或者未关闭,常有的事.Eclipse并不是所有的xml标记都检查,单双标记什么的. 2.有人说,据说是 android a ...

  4. UI开发模式对比:JSP、Android、Flex

    前一篇文章分析了Java平台下不同类型WEB框架对开发模式的影响,多数Java领域的WEB框架都是聚焦于服务端MVC的实现,这些框架对View的支持,通常是基于标准的JSP或类似JSP的模板技术如Fr ...

  5. Android与Swift iOS开发:语言与框架对比

    Swift是现在Apple主推的语言,2014年新推出的语言,比Scala等“新”语言还要年轻10岁.2015年秋已经开源.目前在linux上可用,最近已经支持Android NDK:在树莓派上有Sw ...

  6. Android UI开发第三十一篇——Android的Holo Theme

    好长时间没写Android UI方面的文章了,今天就闲扯一下Android的Holo主题.一直做android开发的可能都知道,Android 系统的UI有过两次大的变化,一次是android 3.0 ...

  7. 【Android】11.0 UI开发(二)——列表控件ListView的简单实现1

    ************************ 转载请注明出处:https://www.cnblogs.com/xiaofu007/p/10342462.html ***************** ...

  8. 【转】Android UI开发第三十一篇——Android的Holo Theme

    好长时间没写Android UI方面的文章了,今天就闲扯一下Android的Holo主题.一直做android开发的可能都知道,Android 系统的UI有过两次大的变化,一次是android 3.0 ...

  9. Android UI开发第三十九篇——Tab界面实现汇总及比较

    Tab布局是iOS的经典布局,Android应用中也有大量应用,前面也写过Android中TAb的实现,<Android UI开发第十八篇——ActivityGroup实现tab功能>.这 ...

随机推荐

  1. Elasticsearch源码分析 - 源码构建

    原文地址:https://mp.weixin.qq.com/s?__biz=MzU2Njg5Nzk0NQ==&mid=2247483694&idx=1&sn=bd03afe5a ...

  2. ORACLE如何检查找出损坏索引(Corrupt Indexes)

      在Oracle数据库中如何找出损坏索引呢? 下面我们人为构造一个案例,将索引块损坏.如下案例所示: SQL> create tablespace test_data   2  datafil ...

  3. USB初学(一)---USB-HID的初步认识【转】

    HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复习一下USB协议的相关内容. USB设备描述符-概述 当插入USB设备后,主机会向设备请求各种描述符来识别设备.那什么是设 ...

  4. python爬虫 | 一条高效的学习路径

    数据是创造和决策的原材料,高质量的数据都价值不菲.而利用爬虫,我们可以获取大量的价值数据,经分析可以发挥巨大的价值,比如: 豆瓣.知乎:爬取优质答案,筛选出各话题下热门内容,探索用户的舆论导向. 淘宝 ...

  5. 我认知的javascript之函数调用

    今天刚好周六没事,又由于工作的原因导致早上醒来就睡不着,无聊之下,就想到了 js 的function调用问题.当然,网上也是对javascript的一些事情说得很透了,但我觉得还是有必要把自己的想法说 ...

  6. kernel笔记——中断

    cpu与磁盘.网卡.键盘等外围设备(相对于cpu和内存而言)交互时,cpu下发I/O请求到这些设备后,相对cpu的处理能力而言,磁盘.网卡等设备需要较长时间完成请求处理. 那么在请求发出到处理完成这段 ...

  7. grep -v、-e、-E

    在Linux的grep命令中如何使用OR,AND,NOT操作符呢? 其实,在grep命令中,有OR和NOT操作符的等价选项,但是并没有grep AND这种操作符.不过呢,可以使用patterns来模拟 ...

  8. SkylineGlobe7.0.1版本 支持SQLite(*.sqlite;*.db)数据库

    SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了 ...

  9. TensorRT&Sample&Python[end_to_end_tensorflow_mnist]

    本文是基于TensorRT 5.0.2基础上,关于其内部的end_to_end_tensorflow_mnist例子的分析和介绍. 1 引言 假设当前路径为: TensorRT-5.0.2.6/sam ...

  10. 面试3——java集合类总结(Set)

    Set 集合 和List一样,继承Collection接口,不同的是Set中不能包含重复的元素,无序,并且最多只能允许一个null值.Set常见的实现类有:HashSet.TreeSet和Linked ...