Android ListView – Holder模式和getItemViewType

简介:

Mobile开发:Android-ListView中介绍了在Android中如何使用ListView,以及为数据模型自定义Item的UI. 这一篇要将两个方面的内容:Holder模式和getItemViewType的应用。

Holder模式

模式这个词语是通过GOF的《设计模式》这本书而引入软件设计领域的。在软件设计领域里面,模式是指为解决特定问题而存在的通用解决方案。这个特定的问题如果在软件设计领域广泛存在,那么该解决方案就有记录和传播的价值。

Holder模式要解决的是性能问题:

场景:在我们的Adapter中每次都要从row中通过findViewById来找到子控件,然后设置值。如果row的布局比较复杂,或者row的数目特别多。这个查找就要不断发生。从而导致性能问题。

方案:在row第一次被构建出来的时候,调用findViewById, 通过Holder对象存储起来,然后把Holder对象通过row.setTag方法,直接缓存在row上。这样下次就不用在查找了。

看看下面的代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    try {
        Restaurant item = this.getItem(position);
        View row = convertView;
        RestaurantListViewItemHolder holder=null;
        if (row == null) {
            LayoutInflater inflater = LayoutInflater
                    .from(this.getContext());
            if(!item.isGoldenBrand())
            row = inflater
                    .inflate(R.layout.restaurant_list_view_item, null);
            else row=inflater.inflate(R.layout.restaurant_list_view_item_golden, null);
 
            holder = createRestaurantListViewItemHolder(row,item.isGoldenBrand());
            row.setTag(holder);
        }else{
            holder=(RestaurantListViewItemHolder)row.getTag();
        }       
 
        holder.UpdateUI(item);
        return row;
    } catch (Exception e) {
        Log.e(LogTags.RestaurantListAdapter, e.getLocalizedMessage(), e);
    }
    return super.getView(position, convertView, parent);
}
 
/**
 * Create a holder for a row in list,when the row is first loaded.
 * @param row
 * @return
 */
private RestaurantListViewItemHolder createRestaurantListViewItemHolder(
        View row,boolean isGoldenBrand) {
    TextView txtName = (TextView) row
            .findViewById(R.id.restaurant_name);
    TextView txtPhoneNR = (TextView) row
            .findViewById(R.id.restaurant_phone_nr);
    TextView txtLocation = (TextView) row
            .findViewById(R.id.restaurant_address);
    ImageView imgIcon=(ImageView) row.findViewById(R.id.restaurent_icon);
    TextView txtDescription=null;
    if(isGoldenBrand)
        txtDescription=(TextView)row.findViewById(R.id.restaurant_description_direct);
    return new RestaurantListViewItemHolder(txtPhoneNR,txtName,txtLocation,
            imgIcon,txtDescription);
}

上面的代码由于混合了和getItemViewType有关的内容。所以看起来有点和上篇中不同。其主要代码在第15,16,18,21行。

  • 第15行:通过调用createRestaurantListViewItemHolder来构造一个Holder对象。
  • 第16行:调用row.setTag将Holder关联到row对象上。
  • 第18行:如果row对象不是新构建的,直接获取row上的Tag,这个Tag对象就是我们在第16行存储的RestaurantListViewItemHolder对象。
  • 第21行:调用holder.UpdateUI来更新UI。

上面的代码中已经用到了RestaurantListViewItemHolder,下面是代码文件。逻辑非常的简单。

package net.lxzhu.mobile;
 
import android.widget.ImageView;
import android.widget.TextView;
 
public class RestaurantListViewItemHolder {
    private TextView phoneNumberUI;
    private TextView nameUI;
    private TextView addressUI;
    private ImageView iconUI;
    private TextView descriptionUI;
 
    public RestaurantListViewItemHolder(TextView phoneNumberUI,
            TextView nameUI, TextView addressUI, ImageView iconUI,TextView descriptionUI) {
        this.phoneNumberUI=phoneNumberUI;
        this.nameUI=nameUI;
        this.addressUI=addressUI;
        this.iconUI=iconUI;
        this.descriptionUI=descriptionUI;
    }
 
    public void UpdateUI(Restaurant data){
        this.phoneNumberUI.setText(data.getPhoneNR());
        this.nameUI.setText(data.getName());
        this.addressUI.setText(data.getAddress());
        this.iconUI.setImageResource(R.drawable.ic_launcher);
        if(this.descriptionUI!=null)
            this.descriptionUI.setText(data.getDescription());
    }
}

getItemViewType

假设我们的UI设计有这样一个需求。如果一家餐馆被评为金牌场馆,那么它可以直接将最近的一条点评显示在列表中,这样用户不用选中或者点击就可以看到评价了。

这就是为什么我们上面的代码中出现了isGoldenBrand这样的代码。到目前为止,我们的ListView中的每个Item都是一样的。而这个需求却让我们根据数据的不同出现了不同的布局。AdapterView已经提供了支持,我们只需要:

  1. 重写getViewTypeCount方法,返回可能出现的布局的数目。
  2. 重写getItemViewType方法,这个方法返回0到getViewTypeCount()-1之间的数字或者IGNORE_ITEM_VIEW_TYPE. 这个方法返回的id必须要和getView方法中返回的View匹配:在getView中返回相同类型View的position, getItemViewType应该返回同一个id.
  3. 在getView中根据数据不同,返回不同的View。

下面是getViewTypeCount和getItemViewType的代码,getView的代码前面已经给出,这里就不在重复了。


@Override
public int getViewTypeCount() {
    return 2;
}
 
@Override
public int getItemViewType(int position) {
    Restaurant data=this.getItem(position);
    if(!data.isGoldenBrand())
        return 0;
    else return 1;
}

其实我们这里的需求不使用这种模式也可以开发出来。但是如果需求中对金牌餐馆的布局和普通餐馆布局有很大的不同的话。这个功能就非常实用了。下面是修改后的代码的执行结果。

image



相关文章
|
Android开发
Android Mediatek 增加Recovery模式下读cmdline的强制工厂重置选项
Android Mediatek 增加Recovery模式下读cmdline的强制工厂重置选项
146 0
|
API Android开发 开发者
Android UI设计: 什么是RecyclerView?为什么它比ListView更好?
Android UI设计: 什么是RecyclerView?为什么它比ListView更好?
248 2
|
XML 前端开发 测试技术
Android基础知识:解释Android的MVC和MVP模式。
Android基础知识:解释Android的MVC和MVP模式。
154 0
|
4月前
|
数据库 Android开发
Android使用EditText+Listview实现搜索效果(使用room模糊查询)
本文介绍如何在Android中使用EditText与ListView实现搜索功能,并结合Room数据库完成模糊查询。主要内容包括:Room的模糊查询语句(使用`||`代替`+`号)、布局美化(如去除ListView分割线和EditText下划线)、EditText回车事件监听,以及查询逻辑代码示例。此外,还提供了相关扩展文章链接,帮助读者深入了解ListView优化、动态搜索及Room基础操作。
307 65
|
4月前
|
Android开发
Android护眼模式(argb)
这是一篇关于实现护眼模式的技术文章。通过动态添加一个透明的帧布局(FrameLayout),并设置其不可触碰、不可聚焦,覆盖在应用界面之上。利用 `Color.argb()` 方法设置带有透明度的背景色,提供两种流行护眼色(浅绿和深绿)。开启护眼模式时,为帧布局设置计算好的颜色;关闭时恢复透明。若需全局生效,可在 BaseActivity 中初始化并调用相关方法。此方案简单高效,适合快速集成护眼功能。
164 1
|
设计模式 Android开发 Kotlin
Android经典实战之Kotlin委托模式和by关键字
本文介绍了Kotlin中`by`关键字在类及属性委托中的运用,通过实例展示了如何利用类委托简化接口实现,以及如何借助标准与自定义属性委托管理属性的读写操作。通过`by`关键字的支持,Kotlin使得委托模式的实现更为直观且高效。
269 4
|
存储 前端开发 测试技术
Android Kotlin中使用 LiveData、ViewModel快速实现MVVM模式
使用Kotlin实现MVVM模式是Android开发的现代实践。该模式分离UI和业务逻辑,借助LiveData、ViewModel和DataBinding增强代码可维护性。步骤包括创建Model层处理数据,ViewModel层作为数据桥梁,以及View层展示UI。添加相关依赖后,Model类存储数据,ViewModel类通过LiveData管理变化,而View层使用DataBinding实时更新UI。这种架构提升代码可测试性和模块化。
460 2
|
API Android开发 开发者
`RecyclerView`是Android API 21引入的UI组件,用于替代ListView和GridView
【6月更文挑战第26天】`RecyclerView`是Android API 21引入的UI组件,用于替代ListView和GridView。它提供高效的数据视图复用,优化的布局管理,支持多种布局(如线性、网格),并解耦数据、适配器和视图。RecyclerView的灵活性、性能(如局部刷新和动画支持)和扩展性使其成为现代Android开发的首选,特别是在处理大规模数据集时。
192 2
|
前端开发 API Android开发
25. 【Android教程】列表控件 ListView
25. 【Android教程】列表控件 ListView
528 2
|
XML Java Android开发
如何美化android程序:自定义ListView背景
如何美化android程序:自定义ListView背景
134 2

热门文章

最新文章