利用ViewHolder优化自定义Adapter的典型写法

  最近写Adapter写得多了,慢慢就熟悉了。

  用ViewHolder,主要是进行一些性能优化,减少一些不必要的重复操作。(WXD同学教我的。)

  具体不分析了,直接上一份代码吧:

public class MarkerItemAdapter extends BaseAdapter
{
private Context mContext = null;
private List<MarkerItem> mMarkerData = null; public MarkerItemAdapter(Context context, List<MarkerItem> markerItems)
{
mContext = context;
mMarkerData = markerItems;
} public void setMarkerData(List<MarkerItem> markerItems)
{
mMarkerData = markerItems;
} @Override
public int getCount()
{
int count = 0;
if (null != mMarkerData)
{
count = mMarkerData.size();
}
return count;
} @Override
public MarkerItem getItem(int position)
{
MarkerItem item = null; if (null != mMarkerData)
{
item = mMarkerData.get(position);
} return item;
} @Override
public long getItemId(int position)
{
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder = null;
if (null == convertView)
{
viewHolder = new ViewHolder();
LayoutInflater mInflater = LayoutInflater.from(mContext);
convertView = mInflater.inflate(R.layout.item_marker_item, null); viewHolder.name = (TextView) convertView.findViewById(R.id.name);
viewHolder.description = (TextView) convertView
.findViewById(R.id.description);
viewHolder.createTime = (TextView) convertView
.findViewById(R.id.createTime); convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
} // set item values to the viewHolder: MarkerItem markerItem = getItem(position);
if (null != markerItem)
{
viewHolder.name.setText(markerItem.getName());
viewHolder.description.setText(markerItem.getDescription());
viewHolder.createTime.setText(markerItem.getCreateDate());
} return convertView;
} private static class ViewHolder
{
TextView name;
TextView description;
TextView createTime;
} }

  其中MarkerItem是自定义的类,其中包含name,description,createTime等字段,并且有相应的get和set方法。

  ViewHolder是一个内部类,其中包含了单个项目布局中的各个控件。

  单个项目的布局,即R.layout.item_marker_item如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:padding="5dp"> <TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="20sp"
android:textStyle="bold" /> <TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Description"
android:textSize="18sp" /> <TextView
android:id="@+id/createTime"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CreateTime"
android:textSize="16sp" /> </LinearLayout>

官方的API Demos中也有这个例子:

package com.example.android.apis.view中的List14:

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package com.example.android.apis.view; import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.ImageView;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import com.example.android.apis.R; /**
* Demonstrates how to write an efficient list adapter. The adapter used in this example binds
* to an ImageView and to a TextView for each row in the list.
*
* To work efficiently the adapter implemented here uses two techniques:
* - It reuses the convertView passed to getView() to avoid inflating View when it is not necessary
* - It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary
*
* The ViewHolder pattern consists in storing a data structure in the tag of the view returned by
* getView(). This data structures contains references to the views we want to bind data to, thus
* avoiding calls to findViewById() every time getView() is invoked.
*/
public class List14 extends ListActivity { private static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Bitmap mIcon1;
private Bitmap mIcon2; public EfficientAdapter(Context context) {
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context); // Icons bound to the rows.
mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_1);
mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_2);
} /**
* The number of items in the list is determined by the number of speeches
* in our array.
*
* @see android.widget.ListAdapter#getCount()
*/
public int getCount() {
return DATA.length;
} /**
* Since the data comes from an array, just returning the index is
* sufficent to get at the data. If we were using a more complex data
* structure, we would return whatever object represents one row in the
* list.
*
* @see android.widget.ListAdapter#getItem(int)
*/
public Object getItem(int position) {
return position;
} /**
* Use the array index as a unique id.
*
* @see android.widget.ListAdapter#getItemId(int)
*/
public long getItemId(int position) {
return position;
} /**
* Make a view to hold each row.
*
* @see android.widget.ListAdapter#getView(int, android.view.View,
* android.view.ViewGroup)
*/
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder; // When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text, null); // Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
} // Bind the data efficiently with the holder.
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2); return convertView;
} static class ViewHolder {
TextView text;
ImageView icon;
}
} @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new EfficientAdapter(this));
} private static final String[] DATA = Cheeses.sCheeseStrings;
}

  其中布局:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView android:id="@+id/icon"
android:layout_width="48dip"
android:layout_height="48dip" /> <TextView android:id="@+id/text"
android:layout_gravity="center_vertical"
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="wrap_content" /> </LinearLayout>

更多关于Adapter优化的文章:

  http://www.cnblogs.com/over140/archive/2011/03/23/1991100.html

  http://www.cnblogs.com/halzhang/archive/2010/12/05/1896791.html

Android中利用ViewHolder优化自定义Adapter的典型写法的更多相关文章

  1. 利用ViewHolder优化自定义Adapter的典型写法

    1 public class MarkerItemAdapter extends BaseAdapter { private Context mContext = null; private List ...

  2. Android中使用ListView绘制自定义表格(2)

    上回再写了<Android中使用ListView绘制自定义表格>后,很多人留言代码不全和没有数据样例.但因为项目原因,没法把源码全部贴上来.近两天,抽空简化了一下,做了一个例子. 效果图如 ...

  3. Android中利用Handler实现消息的分发机制(三)

    在第二篇文章<Android中利用Handler实现消息的分发机制(一)>中,我们讲到主线程的Looper是Android系统在启动App的时候,已经帮我们创建好了,而假设在子线程中须要去 ...

  4. Android中利用ant进行多渠道循环批量打包

    公司负责Android开发的小伙伴学习能力稍微偏弱,交代给他的自动化打包的任务,弄了好久依然没有成效.无奈只好亲自出手. 没有想到过程很顺利,我完全按照如下文章的步骤进行: 主要参考: Android ...

  5. android 中View的优化

    在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候, ...

  6. 那些Android中的性能优化

    性能优化是一个大的范畴,如果有人问你在Android中如何做性能优化的,也许都不知道从哪开始说起. 首先要明白的是,为什么我们的App需要优化,最显而易见的时刻:用户say,什么狗屎,刷这么久都没反应 ...

  7. Android中的布局优化方法

    http://blog.csdn.net/rwecho/article/details/8951009 Android开发中的布局很重要吗?那是当然.一切的显示样式都是由这个布局决定的,你说能不重要吗 ...

  8. Android中ListView 控件与 Adapter 适配器如何使用?

    一个android应用的成功与否,其界面设计至关重要.为了更好的进行android ui设计,我们常常需要借助一些控件和适配器.今天小编在android培训网站上搜罗了一些有关ListView 控件与 ...

  9. Android 中 SQLite 性能优化

    数据库是应用开发中常用的技术,在Android应用中也不例外.Android默认使用了SQLite数据库,在应用程序开发中,我们使用最多的无外乎增删改查.纵使操作简单,也有可能出现查找数据缓慢,插入数 ...

随机推荐

  1. .Net常见错误

    常见错误 #1: 把引用当做值来用,或者反过来 C++ 和其他很多语言的程序员,习惯了给变量赋值的时候,要么赋单纯的值,要么是现有对象的引用.然而,在C# 中,是值还是引用,是由写这个对象的程序员决定 ...

  2. Android系统目录介绍

    src目录:完成对java代码的编写 assets目录: 资源目录 res目录: 图片,布局文件和字符串,菜单等文件 bin目录:输出文件夹 如生成的apk安装文件 project.propertie ...

  3. 报告一个IE很奇葩的滚动条问题——百分比计算宽度为浮点数时的滚动条显示异常

    起因: 做项目的时候做了一个表格内容超过DIV容器自动横向滚动处理.别的浏览器都正常:但是在IE下面明明表格table和容器DIV宽度一致但是却出现了滚动条.如图 然后本人做实验找了半天原因终于是找到 ...

  4. nagios的nrpe的check_command配置优化

    问题处理了两个小时,MMD,各种问题: 先是出现了check_load的时候说参数错误. 然后我就希望 在nagios客户端获取到命令日志 在这篇:NREP将日志放入message中 的引导下终于解决 ...

  5. MVC学习之前必须掌握的c#基础知识

    一.类自动属性 public class Person { //自动属性 public string Name { get; set; } private int _age; public int a ...

  6. C# 读写App.config配置文件的方法

    我们经常会希望在程序中写入一些配置信息,例如版本号,以及数据库的连接字符串等.你可能知道在WinForm应用程序中可以利用Properties.Settings来进行类似的工作,但这些其实都利用了Ap ...

  7. TreeView 自定义显示checkbox

    本项目需要对TreeView进行定制,要求比较简单,主要要求如下: Winform中TreeView控件默认只支持所有级别的CheckBox显示或者不显示,不能控制制定Level的树节点显示 效果如下 ...

  8. Debian7编译VIM7.4

    [ 另: vim7.4源码在vs2013的编译方法 ] 1 安装libncurses5库: apt-get install libncurses5-dev 2 安装gvim需要的库: 方法一: apt ...

  9. 两台Linux主机之间文件的复制

    使用scp命令可以实现两台Linux主机之间的文件复制,基本格式是: scp [可选参数] file_source file_target 1. 复制文件 命令格式: scp local_file r ...

  10. Android接收短信

    Android收到短信时会广播android.provider.Telephony.SMS_RECEIVED消息,因此只要定义一个Receiver,收听该消息,就能接收短信. <receiver ...