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. vue中引用swiper轮播插件

    有时候我们需要在vue中使用轮播组件,如果是在vue组件中引入第三方组件的话,最好通过npm安装,从而进行统一安装包管理. 申明:本文所使用的是vue.2x版本. 通过npm安装插件: npm ins ...

  2. Ansible第一篇:介绍及安装

    Ansible介绍 Ansible是个什么东西呢?官方的title是"Ansible is Simple IT Automation"--简单的自动化IT工具.ansible基于P ...

  3. linux下编译protobuf

    这里我介绍两种方法,一是直接ccmake配置,二是修改cmake文件下面的CMakeList.txt文件 第一种方法:配置ccmake 1.安装sudo apt-get install cmake-c ...

  4. Python使用Plotly绘图工具,绘制水平条形图

    水平条形图与绘制柱状图类似,大家可以先看看我之前写的博客,如何绘制柱状图 水平条形图需要在Bar函数中设置orientation= 'h' 其他的参数与柱状图相同.也可以通过设置barmode = ' ...

  5. 从分治算法到 Hadoop MapReduce

    从分治算法说起 要说 Hadoop MapReduce 就不得不说分治算法,而分治算法其实说白了,就是四个字 分而治之 .其实就是将一个复杂的问题分解成多组相同或类似的子问题,对这些子问题再分,然后再 ...

  6. org.springframework.beans.factory.NoUniqueBeanDefinitionException 导致原因之一

    导致此异常原因很多,以下仅是针对其中一种因素的解决办法. 下面是DAO接口.Service接口.Service实现类的全路径名(全部定义在com.xxx.projetc包下) com.xxx.proj ...

  7. JavaScript(二)数据类型(二)

    布尔值布尔值指真或假,开或关,是或否,关键字true和false.下面这些值会被转换成false: undefined null 0 -0 NaN ""    //  空字符串 布 ...

  8. OKR相关4本书,好书3本

    最近几年看过4本OKR相关的书,有3本是4星.其中第一本是最近看的,剩下3本是2017年看的. OKR源自德鲁克和格鲁夫,跟谷歌是天作之合:4星|<这就是OKR> 4星|<OKR实践 ...

  9. 比较两个slice、struct或者map是否相等

    我们可以直接使用reflect.DeepEqual来比较两个slice.struct或者map是否相等 package main import ( "fmt" "refl ...

  10. 关于c#(vs)dategridview控件继承不能修改的问题

    问题描述:前几天写个小项目的时候,用到了一个父窗体,然后继承过来的dategridview控件不管是属性还是事件都不能修改. 如下图所示: 然后我就在网上找资料,但是有关这个问题的资源甚少,或许是我不 ...