ListView优化adapter getview的两种方式ViewHolder vs HolderView

 一、ViewHolder方式

如果你还没听说过ViewHolder,那么你该去好好看看官方文档了,而不是埋头写代码。

一个ListView的item布局中需要赋值的子元素太多为了避免重复的调用FindViewById方法,我们一般考虑使用ViewHolder方式来实现BaseAdapter。

如下:

//在外面先定义,ViewHolder静态类
static class ViewHolder
{
    public ImageView img;
    public TextView title;
    public TextView info;
}
//然后重写getView
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if(convertView == null)
    {
        holder = new ViewHolder();
        convertView = mInflater.inflate(R.layout.list_item, null);
        holder.img = (ImageView)item.findViewById(R.id.img)
        holder.title = (TextView)item.findViewById(R.id.title);
        holder.info = (TextView)item.findViewById(R.id.info);
        convertView.setTag(holder);
    }else
    {
        holder = (ViewHolder)convertView.getTag();
    }
        holder.img.setImageResource(R.drawable.ic_launcher);
        holder.title.setText("Hello");
        holder.info.setText("World");
    }

    return convertView;
}

ViewHolderconvertView第一次inflate的时候绑定了相关的子元素,并被convertView保存下来(setTag方法),当相同的convertView再次需要显示的时候直接调用convertView的getTag取出ViewHolder,并对ViewHolder中的元素赋值。使用ViewHolder模式避免了没有必要的调用findViewById():因为太多的findViewById也会影响性能,这点不容易考虑到。

二、HolderView方式

在HolderView方式中,目的同样是为了避免反复的调用findViewById,但是我们将这个findViewByIdde 任务交给了一个HolderView对象

@Override
public View getView(int i, View convertView, ViewGroup viewGroup) {
    HolderView holderView;
    // Important to not just null check, but rather to a instanceof
    // since we might get any subclass of view here.
    if (convertView instanceof HolderView) {
        holderView = (HolderView) convertView;
    } else {
        holderView = new HolderView(mContext);
    }
    holderView.bind("标题", R.drawable.ic_launcher, "sajsa");
    return holderView;
}
public class HolderView extends GridLayout {
    private ImageView img;
    private TextView title;
    private TextView info;
    public HolderView(Context context, AttributeSet attrs) {
        super(context, attrs);
        View v = LayoutInflater.from(context).inflate(R.layout.list_item, this);
        title = (TextView) v.findViewById(R.id.title);
        img = (ImageView)item.findViewById(R.id.img)
        info = (TextView)item.findViewById(R.id.info);
    }
    public void bind(String stringtitle,int imgrsc, String stringinfo) {
        title.setText(stringtitle);
        img.setImageResource(imgrsc);
        info.setText(stringinfo);
    }
}

HolderView自己维护一个子元素的集合,同时对外提供绑定数据的公共方法bind。HolderView方式的思想是:对于ListView来讲,每一个Item本身是同一个类只是数据不同。但是需要注意的是使用HolderView方式在Adapter中getView返回的是HolderView对象。

总结:ViewHolder方式使用简单,HolderView方式更符合面向对象规范。

时间: 2024-08-02 07:38:56

ListView优化adapter getview的两种方式ViewHolder vs HolderView的相关文章

实现顶部轮播,下部listview经典布局的两种方式

开头: 在做android开发的时候,我们经常会遇到这样的布局,上面是一个图片轮播图,下面是一些列表的项目.很多新闻app,视频类app都采用这样的布局.起初的时候 由于没有很多参考,我自己想到了一种实现方式,就是用scrollview作为外面最大的布局,然后里面嵌套viewpager和listview,但是我现在非常不推荐这种方式,一方面由于这种方式 需要将listview完全展开,缺少了getview函数中应该有的复用与优化.而且结构嵌套复杂.经过一番查找与学习,学习到两种比较规范或者结构比

【REACT NATIVE 系列教程之十三】利用LISTVIEW与TEXTINPUT制作聊天/对话框&&获取组件实例常用的两种方式

本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/react-native/2346.html 本篇Himi来利用ListView和TextInput这两种组件实现对话.聊天框. 首先需要准备的有几点:(组件的学习就不赘述了,简单且官方有文档) 1. 学习下 ListView: 官方示例:http://reactnative.cn/docs/0.27/tutorial.html#content

Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比--转载

 在加载大量数据的时候,经常会用到异步加载,所谓异步加载,就是把耗时的工作放到子线程里执行,当数据加载完毕的时候再到主线程进行UI刷新.在数据量非常大的情况下,我们通常会使用两种技术来进行异步加载,一是通过AsyncTask来实现,另一种方式则是通过ThreadPool来实现,今天我们就通过一个例子来讲解和对比这两种实现方式.     项目的结构如下所示:     在今天这个例子里,我们用到了之前一篇文章中写过的一个自定义控件,如果有同学感兴趣的话可以点击这里来先研究下这个控件的实现,为了配合异

[Android] Android ViewPager 中加载 Fragment的两种方式 方式(二)

接上文: https://www.cnblogs.com/wukong1688/p/10693338.html Android ViewPager 中加载 Fragmenet的两种方式 方式(一) 二.使用Fragment来填充ViewPager Google 官方是建议我们使用Fragment来填充ViewPager的,这样可以更加方便的生成每个Page以及管理 每个Page的生命周期!当然它给我们提供了两个不同的Adapter,他们分别是: FragmentPageAdapter和Fragm

JAVA中创建字符串的两种方式的区别

我们知道,通常在Java中创建一个字符串会有两种方式,通过双引号直接赋值和通过构造器来创建. String x = "abcd"; String y = new String("abcd"); 然而,这两种方式之间的区别是什么?分别应用于哪些情况,之前还不是很懂. 1.双引号的方式 String x = "abcd"; String y = "abcd"; System.out.println(x==y);//true Sys

CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking)

CSharpGL(18)分别处理glDrawArrays()和glDrawElements()两种方式下的拾取(ColorCodedPicking) 我在(Modern OpenGL用Shader拾取VBO内单一图元的思路和实现)记录了基于Color-Coded-Picking的拾取方法. 最近在整理CSharpGL时发现了一个问题:我只解决了用glDrawArrays();渲染时的拾取问题.如果是用glDrawElements();进行渲染,就会得到错误的图元. 本文就彻底解决这个拾取的问题.

android 向服务器Get和Post请求的两种方式,android向服务器发送文件,自己组装协议和借助第三方开源

/** * @author [email protected] * @time 20140606 */ package com.intbird.utils; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream

sparkStreaming读取kafka的两种方式

概述 Spark Streaming 支持多种实时输入源数据的读取,其中包括Kafka.flume.socket流等等.除了Kafka以外的实时输入源,由于我们的业务场景没有涉及,在此将不会讨论.本篇文章主要着眼于我们目前的业务场景,只关注Spark Streaming读取Kafka数据的方式. Spark Streaming 官方提供了两种方式读取Kafka数据: 一是Receiver-based Approach.该种读取模式官方最先支持,并在Spark 1.2提供了数据零丢失(zero-d

对Java代码加密的两种方式,防止反编译

使用Virbox Protector对Java项目加密有两种方式,一种是对War包加密,一种是对Jar包加密.Virbox Protector支持这两种文件格式加密,可以加密用于解析class文件的java.exe,并且可以实现项目源码绑定制定设备,防止部署到客户服务器的项目被整体拷贝. 两种加密方式 War 包加密 当你的项目在没有完成竣工的时候,不适合使用 war 文件,因为你的类会由于调试之类的经常改,这样来回删除.创建 war 文件很不爽,最好是你的项目已经完成了,不改了,那么就打个 w