Android中利用ViewHolder优化自定义Adapter的写法(必看)

发布时间 - 2026-01-11 00:42:17    点击率:

最近写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>

以上这篇Android中利用ViewHolder优化自定义Adapter的写法(必看)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# adapter  # viewholder  # Android自定义实现BaseAdapter的优化布局  # android listview优化几种写法详细介绍  # Android开发中ListView自定义adapter的封装  # Android自定义Adapter的ListView的思路及代码  # 给大家  # 自定义  # 是一个  # 也有  # 希望能  # 得多  # 这篇  # 教我  # 必看  # 小编  # 大家多多  # 主要是  # 其中包含  # 上一份  # 有相应  # 包含了  # schemas  # apk  # res  # xmlns 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在云主机快速搭建网站站点?  北京网站制作的公司有哪些,北京白云观官方网站?  香港服务器网站卡顿?如何解决网络延迟与负载问题?  如何用5美元大硬盘VPS安全高效搭建个人网站?  如何在搬瓦工VPS快速搭建网站?  Windows10如何删除恢复分区_Win10 Diskpart命令强制删除分区  实例解析angularjs的filter过滤器  Laravel怎么清理缓存_Laravel optimize clear命令详解  Laravel用户密码怎么加密_Laravel Hash门面使用教程  详解Android中Activity的四大启动模式实验简述  Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】  如何实现建站之星域名转发设置?  如何在 React 中条件性地遍历数组并渲染元素  大连 网站制作,大连天途有线官网?  如何用花生壳三步快速搭建专属网站?  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  如何在新浪SAE免费搭建个人博客?  googleplay官方入口在哪里_Google Play官方商店快速入口指南  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  怎么用AI帮你设计一套个性化的手机App图标?  php在windows下怎么调试_phpwindows环境调试操作说明【操作】  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】  如何在IIS中配置站点IP、端口及主机头?  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  Android 常见的图片加载框架详细介绍  如何基于PHP生成高效IDC网络公司建站源码?  如何快速生成橙子建站落地页链接?  如何在IIS中新建站点并解决端口绑定冲突?  Android滚轮选择时间控件使用详解  详解Android图表 MPAndroidChart折线图  零服务器AI建站解决方案:快速部署与云端平台低成本实践  今日头条微视频如何找选题 今日头条微视频找选题技巧【指南】  网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?  网站建设要注意的标准 促进网站用户好感度!  如何用免费手机建站系统零基础打造专业网站?  湖南网站制作公司,湖南上善若水科技有限公司做什么的?  Laravel如何生成URL和重定向?(路由助手函数)  JavaScript如何实现倒计时_时间函数如何精确控制  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  Laravel如何实现本地化和多语言支持?(i18n教程)  Laravel如何实现API版本控制_Laravel版本化API设计方案  使用Dockerfile构建java web环境  Laravel怎么自定义错误页面_Laravel修改404和500页面模板  Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制