Android中利用ViewHolder优化自定义Adapter的典型写法
利用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的典型写法的更多相关文章
- 利用ViewHolder优化自定义Adapter的典型写法
1 public class MarkerItemAdapter extends BaseAdapter { private Context mContext = null; private List ...
- Android中使用ListView绘制自定义表格(2)
上回再写了<Android中使用ListView绘制自定义表格>后,很多人留言代码不全和没有数据样例.但因为项目原因,没法把源码全部贴上来.近两天,抽空简化了一下,做了一个例子. 效果图如 ...
- Android中利用Handler实现消息的分发机制(三)
在第二篇文章<Android中利用Handler实现消息的分发机制(一)>中,我们讲到主线程的Looper是Android系统在启动App的时候,已经帮我们创建好了,而假设在子线程中须要去 ...
- Android中利用ant进行多渠道循环批量打包
公司负责Android开发的小伙伴学习能力稍微偏弱,交代给他的自动化打包的任务,弄了好久依然没有成效.无奈只好亲自出手. 没有想到过程很顺利,我完全按照如下文章的步骤进行: 主要参考: Android ...
- android 中View的优化
在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候, ...
- 那些Android中的性能优化
性能优化是一个大的范畴,如果有人问你在Android中如何做性能优化的,也许都不知道从哪开始说起. 首先要明白的是,为什么我们的App需要优化,最显而易见的时刻:用户say,什么狗屎,刷这么久都没反应 ...
- Android中的布局优化方法
http://blog.csdn.net/rwecho/article/details/8951009 Android开发中的布局很重要吗?那是当然.一切的显示样式都是由这个布局决定的,你说能不重要吗 ...
- Android中ListView 控件与 Adapter 适配器如何使用?
一个android应用的成功与否,其界面设计至关重要.为了更好的进行android ui设计,我们常常需要借助一些控件和适配器.今天小编在android培训网站上搜罗了一些有关ListView 控件与 ...
- Android 中 SQLite 性能优化
数据库是应用开发中常用的技术,在Android应用中也不例外.Android默认使用了SQLite数据库,在应用程序开发中,我们使用最多的无外乎增删改查.纵使操作简单,也有可能出现查找数据缓慢,插入数 ...
随机推荐
- Windows Azure Affinity Groups (3) 修改虚拟网络地缘组(Affinity Group)的配置
<Windows Azure Platform 系列文章目录> 本文介绍的是国内使用世纪互联运维的Azure China 在笔者之前的文章中,我们知道现在微软官方不建议使用Affinity ...
- [New Portal]Windows Azure Virtual Machine (19) 关闭Azure Virtual Machine与VIP Address,Internal IP Address的关系(1)
<Windows Azure Platform 系列文章目录> 默认情况下,通过Azure Management Portal创建的Public IP和Private IP都是随机分配的. ...
- JAVA 设计模式 代理模式
用途 代理模式 (Proxy) 为其他对象提供一种代理以控制对这个对象的访问. 代理模式是一种结构型模式. 结构
- JAVA 设计模式 组合模式
用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模式. 结构
- Elasticsearch Span Query跨度查询
ES基于Lucene开发,因此也继承了Lucene的一些多样化的查询,比如本篇说的Span Query跨度查询,就是基于Lucene中的SpanTermQuery以及其他的Query封装出的DSL,接 ...
- SQL Server中的事务日志管理(8/9):优化日志吞吐量
当一切正常时,没有必要特别留意什么是事务日志,它是如何工作的.你只要确保每个数据库都有正确的备份.当出现问题时,事务日志的理解对于采取修正操作是重要的,尤其在需要紧急恢复数据库到指定点时.这系列文章会 ...
- noip模拟赛 纸壳子
Task 1.纸壳子(box.pas/box.c/box.cpp) [题目描述] Mcx是一个有轻度洁癖的小朋友.有一天,当他沉溺于数学卷子难以自拔的时候,恍惚间想起在自己当初学习概率的时候准备的一堆 ...
- XML基础学习01
XML学习 1:XML:可扩展的标识语言,是一种描述结构数据的格式,简化了网络中数据交换和表示,使得代码,数据和表示分离,并作为数据交换的标准格式,被称为智能数据文档. 2:当我们不使用数据库来存储数 ...
- Windows Phone中扩展WebBrowser使其支持绑定html内容
在WP开发中,有时候会用到WebBrowser控件来展示一些html内容,这个控件有很多局限性,比如不支持绑定内容,这样的MVVM模式中就无法进行内容的绑定.为了实现这个目的,需要扩展一下,具体代码如 ...
- Ext.NET 4.1 系统框架的搭建(后台) 附源码
Ext.NET 4.1 系统框架的搭建(后台) 附源码 代码运行环境:.net 4.5 VS2013 (代码可直接编译运行) 预览图: 分析图: 上面系统的构建包括三块区域:North.West和C ...