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. 在AndroidStudio上使用AddressSanitizer

    在AndroidStudio上使用AddressSanitizer AddressSanitizer是Google主导的一个开源内存问题检测工具.现在也开始支持Android平台,且受Google推荐 ...

  2. (详细)华为荣耀V10 BKL-AL00的USB调试模式在哪里打开的步骤

    每当我们使用pc连接安卓手机的时候,如果手机没有开启Usb开发者调试模式,pc则无法成功检测到我们的手机,有时我们使用的一些功能比较强的的app比如以前我们使用的一个app引号精灵,老版本就需要开启U ...

  3. eclipse如何修改android工程的包名?

    在我们android项目开发到一定的程度时由于需要,我们必须修改一下工程的包名,以便更好的发布我们的项目.但是在这个过程中有时候修改好了之后会出现一些错误.下面由小编一步步教你如何更改包名,和解决出现 ...

  4. 前后端分离djangorestframework——认证组件

    authentication 认证是干嘛的已经不需要多说.而前后端未分离的认证基本是用cookie或者session,前后端分离的一般用token 全局认证 先创建一个django项目,项目名为drf ...

  5. 含有package关键字的java文件在命令行运行报错

    程序中含有package关键字,使用命令行运行程序时出现"找不到或无法加载主类",而使用Eclipse软件可以正常运行程序的可能解决办法. 在包下的类,在Java源文件的地方编译后 ...

  6. MySql 学习之路-Date函数

    MySQL中重要的内建函数 函数 描述 NOW() 返回当前的日期和时间 NOW() 返回当前的日期和时间. 语法 NOW() -- 实例 -- 下面是 SELECT 语句: SELECT NOW() ...

  7. 软件设计之Deep Module(深模块)

    类是不是越小越好?最近在读John Ousterhout的<A Philosophy of Software Design>,感到作者文笔流畅,书中内容具有启发性.这里摘要一部分内容,以供 ...

  8. CSS伪元素:before/CSS伪元素:before/:after content 显示Font Awesome字体图标:after content 显示Font Awesome字体图标

    HTML <a href="javascript:volid(0);"><i class="icon-table"></i> ...

  9. 3.15 总结,初始java

  10. web开发-Django博客系统

    项目界面图片预览 项目代码github地址 项目完整流程 项目流程: 1 搞清楚需求(产品经理) (1) 基于用户认证组件和Ajax实现登录验证(图片验证码) (2) 基于forms组件和Ajax实现 ...