`

Android中ListView的缓存机制

 
阅读更多

一、ListView 的运行机制
1、使用match_parent 定义ListView 的高度和宽度属性。
定义 ListView 控件的高度和宽度要避免使用wrap_content,否则会导致BaseAdapter.getView 重复调用N次,尽量使用match_parent或固定值设置height和width。


2、缓存列表项
ListView 控件在设计上采用了只创建并显示当前屏幕中的列表项的布局对象(该布局对象由BaseAdapter.getView方法的convertView参数保存)。


例如:一屏显示十个列表项(包括部分显示在屏幕上的列表项),则只创建十个convertView,ListView会反复使用这十个convertView显示进入当前的列表项的内容。
在向上滚屏时,当第一个convertView移出屏幕,该convertView将从屏幕下边出现。同理,在向下滚屏时,若屏幕最下边的convertView移出屏幕,该convertView移出屏幕,该convertView从最上边进入屏幕。

提示:
一屏不一定显示十个列表项,具体多少根据列表项布局的高度和设备的高度而定。



实例案例:

 

package com.jxust.day05_08_listviewoptimize;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

	ListView mlvContact;
	List<ContactBean> mContacts;
	ContactAdapter mAdapter;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initData();
		initView();
	}

	private void initView() {
		mlvContact = (ListView) findViewById(R.id.lvContact);
		mAdapter = new ContactAdapter(mContacts, this);	//	创建适配器	
		mlvContact.setAdapter(mAdapter);	//	配置适配器
	}

	private void initData() {
		String[] names = getResources().getStringArray(R.array.names);
		String[] phones = getResources().getStringArray(R.array.phones);
		mContacts = new ArrayList<ContactBean>();
		for(int i = 0; i < phones.length;i++){
			ContactBean contact = new ContactBean(names[i],phones[i]);
			mContacts.add(contact);
		}
	}

	class ContactAdapter extends BaseAdapter{
		List<ContactBean> contacts;
		MainActivity context;
		
		public ContactAdapter(List<ContactBean> contacts, MainActivity context) {
			super();
			this.contacts = contacts;
			this.context = context;
		}

		// 内部集合的长度
		@Override
		public int getCount() {
			
			return contacts.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return 0;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			Log.i("main", "position="+position);
			ViewHolder holder = null;
			if(convertView == null){// 表示第一屏尚未创建列表项,convertView就表示的是null
				convertView = View.inflate(context, R.layout.item_contact, null);	//创建布局
				holder = new ViewHolder();
				//把convertView获取到布局的属性赋给ViewHolder对象
				holder.tvName = (TextView) convertView.findViewById(R.id.tvName);	
				holder.tvPhone = (TextView) convertView.findViewById(R.id.tvPhone);
				convertView.setTag(holder);	//	tag是View中一个属性,是Object类型的
			}else{// 以后的滚动,出现其它的列表项
				// 这样就可以避免重复解析,提高效率
				holder = (ViewHolder) convertView.getTag();
			}
			// 取出当前的联系人
			ContactBean contact = contacts.get(position); 
			holder.tvName.setText(contact.getName());
			holder.tvPhone.setText(contact.getPhone());
			return convertView;
		}
		
		// 存放item_contact.xml中的两个部件
		class ViewHolder{
			TextView tvName,tvPhone;
		}

	}
}

 

 

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <!-- listView中的width和height要设置成match_parent可以避免BaseAdapter.getView 重复调用 -->
    <ListView
        android:id="@+id/lvContact"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:divider="#ccc"
        android:dividerHeight="10dp" />

</RelativeLayout>

 

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/tvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="张飞"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/tvPhone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:text="13011335577"
        android:textSize="20sp" />

</LinearLayout>

 

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Day05_08_ListViewOptimize</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string-array name="names">
        <item>张飞</item>
        <item>王菲</item>
        <item>刘亦菲</item>
        <item>黄飞鸿</item>
        <item>李菲</item>
        <item>陈菲</item>
        <item>赵菲</item>
        <item>田菲</item>
        <item>郑菲</item>
        <item>邓菲</item>
        <item>岳飞</item>
        <item>郝菲</item>
        <item>咖啡</item>
        <item>啡啡</item>
    </string-array>
    <string-array name="phones">
        <item>13011335577</item>
        <item>13155335577</item>
        <item>13311335577</item>
        <item>13511335577</item>
        <item>13711335577</item>
        <item>13811335577</item>
        <item>13911335577</item>
        <item>15011335577</item>
        <item>13111335577</item>
        <item>18211335577</item>
        <item>18911335577</item>
        <item>13088335577</item>
        <item>13399335577</item>
        <item>13078335577</item>
    </string-array>
</resources>

 

 

 

通过在logcat观察发现,经过对convertView的处理,避免了重复解析,从而提高了效率。

 

并且,特别要注意的是activity_main.xml中有关width和height的取值,我们最好是选择match_parent



 

 

否则:

 

发现,BaseAdapter.getView被重复调用了3次,这样就会导致资源的浪费。

 

 

但是如果我们使用match_parent

 



 

  • 大小: 99.2 KB
  • 大小: 32.4 KB
  • 大小: 85.3 KB
1
0
分享到:
评论

相关推荐

    ListView缓存机制

    ListView是Android平台上常用的一种...总的来说,理解并合理运用ListView的缓存机制是提升Android应用性能的重要手段。开发者需要根据具体项目需求,结合优化策略,确保ListView在处理大量数据时能保持优秀的用户体验。

    android中ListView下拉刷新

    在Android开发中,ListView是一种常用的组件,用于展示大量的列表数据。它通过滚动的方式高效地管理视图,使得只渲染屏幕可见的部分,从而节省系统资源。然而,随着移动应用的不断发展,用户对交互体验的需求也在...

    Android之ListView列表视图和界面跳转实现

    - **复用视图**:为了提高性能,ListView使用了视图缓存机制。在`getView()`中,我们检查`convertView`是否为空,如果非空,则重用已有的视图,避免频繁创建新视图。 - **ViewHolder模式**:为了进一步提升性能,...

    Android中ListView实现表格效果

    在Android开发中,ListView是一种非常常见的控件,用于展示大量数据列表。然而,有时我们不仅需要展示单一列表,还可能需要实现类似表格的效果,比如显示多列数据。本篇文章将详细讲解如何在Android中利用ListView...

    android 中ListView下载图片

    3. **图片缓存策略**:异步加载库通常都支持缓存机制,包括内存缓存和磁盘缓存。当图片加载时,首先检查内存缓存,如果存在则直接使用;若不在内存中,再从磁盘读取或从网络下载。这样可以减少网络请求,提高用户...

    Android实现ListView异步加载图片

    本文将详细介绍 Android 中实现 ListView 异步加载图片的方法,并对相关的技术概念进行解释。 1. 异步加载图片的必要性 在 Android 应用程序中,加载图片是一个耗时的操作,特别是在 ListView 中。如果不使用异步...

    android SQlite、listView中加按钮的使用

    在Android开发中,SQLite是一个非常重要的本地数据存储机制,它是一个轻量级的数据库,能够帮助开发者在应用程序中实现数据的持久化。SQLite支持多种数据类型,如整型、浮点型、字符串和二进制数据,使得它可以适应...

    android 嵌套的listview示例

    利用ListView的缓存机制,重用convertView,减少不必要的对象创建。 - 使用`HeaderView`和`FooterView`可以避免在Item中创建复杂的布局,提高效率。 - 对于子ListView,尽可能使用`RecycleView`代替`ListView`,...

    Android ListView扩展(图片+文字)

    可以使用LruCache或其他缓存机制来存储已加载的图片,减少内存占用。 9. 动态加载:在实际应用中,数据可能来自网络或数据库。这时,你需要在后台线程中异步加载数据,然后更新Adapter,调用`notifyDataSetChanged...

    android中listview实现下拉自动分页刷新资源

    在Android应用开发中,ListView是展示大量数据列表的常用组件,尤其在实现分页加载和下拉刷新功能时,它的作用更加突出。本教程将详细讲解如何在Android中利用ListView实现下拉自动分页刷新的功能。 首先,我们需要...

    Android中ListView全面完美的网络图片的异步加载

    综上所述,实现Android中ListView全面完美的网络图片异步加载需要结合异步加载库(如Picasso或Glide)、LruCache缓存策略以及动态加载技术。这些方法的运用可以显著提升应用性能,为用户提供流畅的滚动体验,同时...

    在Android中ListView多种Item布局的实现

    为了优化ListView的性能,还可以使用缓存机制,比如使用`convertView`。当一个Item离开屏幕后,它的View会被回收,供后续需要创建的新Item复用。通过判断`convertView`是否为null,我们可以决定是复用已有的View还是...

    Android 中ListView的应用

    在Android开发中,ListView是一个非常重要的组件,它用于展示大量数据列表,通常用于实现像通讯录、消息列表等效果。ListView的高效利用是优化用户体验的关键,因为它能够动态加载数据,只渲染屏幕可见的部分,从而...

    Android中ListView,SQLite,BaseAdapter的结合源码

    在Android开发中,ListView、SQLite和BaseAdapter是三个至关重要的组件,它们共同协作,使得应用程序能够展示和管理大量数据。ListView是一种可滚动的视图,用于显示一系列项,而SQLite是一个轻量级的数据库系统,...

    android打造listview通用适配器

    在Android开发中,ListView是展示数据列表常用的组件。然而,为ListView设置适配器和创建ViewHolder经常需要重复编写相似的代码。"android打造listview通用适配器"这个主题旨在解决这个问题,通过创建一个可复用的...

    Android 解决ListView的复用问题 demo

    在Android开发中,ListView是常用的一种控件,用于展示大量数据列表。然而,由于性能考虑,ListView采用了一种称为“视图复用”的机制来优化显示效率,这就是我们所说的“ListView复用问题”。本demo主要展示了如何...

    Android中ListView视图的回收数据机制.pdf

    如果Adapter中定义了不同的视图类型,RecycleBin会为每种类型提供单独的缓存机制,确保不同类型视图的正确复用。 **2. ListView数据回收的流程** - 当用户滚动ListView时,一些视图会离开屏幕,此时ListView调用`...

    Android自定义ListView图片从服务端获取

    图片加载库如Glide和Picasso已经内置了这些缓存机制,我们只需配置好缓存大小即可。 4. **ListView的优化**: - 使用ViewHolder模式:减少findViewById的调用,提高列表滑动的流畅性。 - 图片加载监听:通过监听...

Global site tag (gtag.js) - Google Analytics