android:提升 ListView 的运行效率

之所以说 ListView 这个控件很难用,就是因为它有很多的细节可以优化,其中运行效率 就是很重要的一点。目前我们 ListView 的运行效率是很低的,因为在 FruitAdapter 的 getView() 方法中每次都将布局重新加载了一遍,当 ListView 快速滚动的时候这就会成为性能的瓶颈。

仔细观察,getView()方法中还有一个 convertView 参数,这个参数用于将之前加载好的 布局进行缓存,以便之后可以进行重用。修改 FruitAdapter 中的代码,如下所示:

public class FruitAdapter extends ArrayAdapter<Fruit> {

……

@Override

public View getView(int position, View convertView, ViewGroup parent) { Fruit fruit = getItem(position);

View view;

if (convertView == null) {

view = LayoutInflater.from(getContext()).inflate(resourceId, null);

} else {

view = convertView;

}

ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image); TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());

return view;

}

}

可以看到,现在我们在 getView()方法中进行了判断,如果 convertView 为空,则使用 LayoutInflater 去加载布局,如果不为空则直接对 convertView 进行重用。这样就大大提高了
ListView 的运行效率,在快速滚动的时候也可以表现出更好的性能。

不过,目前我们的这份代码还是可以继续优化的,虽然现在已经不会再重复去加载布局,
但是每次在 getView()方法中还是会调用 View 的 findViewById()方法来获取一次控件的实例。
我们可以借助一个 ViewHolder 来对这部分性能进行优化,修改 FruitAdapter 中的代码,如下
所示:

public class FruitAdapter extends ArrayAdapter<Fruit> {

……

@Override

public View getView(int position, View convertView, ViewGroup parent) { Fruit
fruit = getItem(position);

View view;

ViewHolder viewHolder;

if (convertView == null) {

view = LayoutInflater.from(getContext()).inflate(resourceId, null);

viewHolder = new ViewHolder();

viewHolder.fruitImage = (ImageView) view.findViewById

(R.id.fruit_image);

viewHolder.fruitName = (TextView) view.findViewById

(R.id.fruit_name);

view.setTag(viewHolder); // ViewHolder存储在View

} else {

view = convertView;

viewHolder = (ViewHolder) view.getTag();
//
重新获取ViewHolder

}
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitName.setText(fruit.getName());

return view;

}

class ViewHolder { ImageView fruitImage;
TextView fruitName;

}

}

我们新增了一个内部类 ViewHolder,用于对控件的实例进行缓存。当 convertView 为空 的时候,创建一个 ViewHolder 对象,并将控件的实例都存放在 ViewHolder 里,然后调用 View 的 setTag()方法,将 ViewHolder 对象存储在 View 中。当 convertView 不为空的时候则调用 View 的 getTag()方法,把 ViewHolder 重新取出。这样所有控件的实例都缓存在了 ViewHolder
里,就没有必要每次都通过 findViewById()方法来获取控件实例了。

通过这两步的优化之后,我们 ListView 的运行效率就已经非常不错了。

3.5.4    ListView 的点击事件

话说回来,ListView 的滚动毕竟只是满足了我们视觉上的效果,可是如果 ListView 中的 子项不能点击的话,这个控件就没有什么实际的用途了。因此,本小节中我们就来学习一下 ListView 如何才能响应用户的点击事件。

修改 MainActivity 中的代码,如下所示:

public class MainActivity extends Activity {

private List<Fruit> fruitList = new
ArrayList<Fruit>();

@Override

protected void
onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initFruits();

FruitAdapter adapter = new
FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);

ListView listView = (ListView)
findViewById(R.id.list_view); listView.setAdapter(adapter);
listView.setOnItemClickListener(new OnItemClickListener() {

@Override

public void
onItemClick(AdapterView<?> parent, View view, int position, long id) {

Fruit fruit = fruitList.get(position);
Toast.makeText(MainActivity.this, fruit.getName(),

Toast.LENGTH_SHORT).show();

}

});

}

……

}

可以看到,我们使用了 setOnItemClickListener()方法来为 ListView 注册了一个监听器,
当用户点击了 ListView 中的任何一个子项时就会回调 onItemClick()方法,在这个方法中可以
通过
position 参数判断出用户点击的是哪一个子项,然后获取到相应的水果,并通过 Toast 将水果的名字显示出来。

重新运行程序,并点击一下西瓜,效果如图 3.31 所示。

图   3.31

时间: 2024-08-07 12:04:48

android:提升 ListView 的运行效率的相关文章

Android——提升ListView的运行效率

之所以说 ListView 这个控件很难用,就是因为它有很多的细节可以优化,其中运行效率就是很重要的一点.目前我们ListView 的运行效率是很低的,因为在 FruitAdapter 的getView()方法中每次都将布局重新加载了一遍,当 ListView 快速滚动的时候这就会成为性能的瓶颈. 仔细观察,getView()方法中还有一个 convertView 参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用.修改 FruitAdapter 中的代码,如下所示: 1 pub

Android中ListView的使用以及提升ListView的运行效率

ListView是安卓中非常常用的一个控件,可以用来展示一系列的数据,下面来介绍下ListView的用法和如何提升ListView的效率 ListView的使用遵循MVC模式,m是实体,v是视图(即为ListView),C是控制器(即未适配器adapter) 使用ListView一般可以遵循以下步骤 一.定义一个ListView展示的条目的布局 list_item.xml <?xml version="1.0" encoding="utf-8"?> &l

提升ListView的运行效率

目前我们ListView的运行效率是很低的,因为每次getView()方法中每次都将布局重新加载一遍, 当ListView快速滚动的时候就会成为性能的瓶颈 解决办法:在getView()方法中还有一个convertView参数,这个参数用于将之前加载好的布局进行缓存, 以便之后进行重用,所以在getView()方法中进行判断,如果convertView为空,则使用LayoutInflater 去加载布局,如果不为空,则直接对convertView进行重用,这样就打打提高了ListView的运行效

提升ListView运行效率两个方法

一.首先我们先实现ListView的构建工作 1.定义一个实体类,作为ListView适配器的适配类型.新建Fruit类,代码如下: package org.lxh.demo; public class Fruit { private String name; private int imageId; public Fruit(String name, int imageId) { this.name = name; this.imageId = imageId; } public String

初识ListView - 定制ListView - 提升ListView运行效率

ListView绝对可以称得上是 Android 中最常用的控件之一,几乎所有的应用程序都会用到它.由于手机屏幕空间都比较有限,能够一次性在屏幕上显示的内容并不多,当我们的程序中有大量的数据需要展示的时候,就可以借助 ListView来实现.ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚动出屏幕.相信你其实每天都在使用这个控件,比如查看手机联系人列表,翻阅微博的最新消息等等.不过比起前面介绍的几种控件,ListView的用法也相对复杂了很多.

Android之ListView

作用:以item的形式用来显示大量的数据. 使用步骤: 1.XML中使用<ListView>标签 2.Dada —> String[]数组(数据来源) 3.ArrayAdapter<String> adapter=new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data); –>适配器(用来将数据和控件进行绑定 4.  myListView.se

Android学习--ListView

这篇文章用于总结自己这两天学到的安卓的ListView和RecyclerView 的笔记,以及从我这个iOS开发者的角度去理解和学习这两个控件,会比较一下他们个iOS中那些控件是一致的,可以用来对比的. 一:ListView 最简单的用法 ListView最简单的用法无非就是用它写一个最基本的列表界面,展示的数据也就是我们最基本和常见的单条数据,一步一步的走下去: ListView的创建,先说说它的布局的创建,直接代码了,很简单的一个ListView的宽.高和id: 布局文件创建完之后就是我们的

Android 解决ListView在使用多个布局的同时使用convertView进行缓存时导致ListView下面有空白的问题

在使用ListView时,在Adapter里面使用convertView会提高ListView的性能,提升100%?但今天发现在listView同时加载不同的View的同时会导致ListView最底下有一块空白,可能是恰巧吧,导致这样的原因可能是加载了几个不同的View,而他们的高度不同,数量也不同,系统无法准确计算ListView的总高度. 在 BaseAdapter里面提供了两个回调函数来指定有多少种布局,指定position对应的是哪一个布局. @Override public int g

Android杂谈--ListView之BaseAdapter的使用

前言 话说开发用了各种Adapter之后感觉用的最舒服的还是BaseAdapter,尽管使用起来比其他适配器有些麻烦,但是使用它却能实现很多自己喜欢的列表布局,比如ListView.GridView.Gallery.Spinner等等.它是直接继承自接口类Adapter的,使用BaseAdapter时需要重写很多方法,其中最重要的当属getView,因为这会涉及到ListView优化等问题,其他的方法可以参考链接的文章 BaseAdapter与其他Adapter有些不一样,其他的Adapter可