Android ListView 优化之 getView 与 ViewHolder 是如何工作的?

   2016-11-07 0
核心提示:Android中我们经常会用到ListView,然后ListView到底是如何通过ViewHolder去优化的?1.常见的适配器中利用ViewHolder去优化ListView的代码@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder;if (conve

Android中我们经常会用到ListView,然后ListView到底是如何通过ViewHolder去优化的?

1.常见的适配器中利用ViewHolder去优化ListView的代码

@Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
            viewHolder = new ViewHolder();
            viewHolder.textView = (TextView) convertView.findViewById(R.id.textView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        String name = datas.get(position);
        viewHolder.textView.setText(name);
        return convertView;
    }

    private class ViewHolder {
        public TextView textView;
    }

其实大家应该去思考一个问题,为什么要这么去写?大多数人可能只知道是优化的,但是是如何进行优化的呢?

2.关于getView的调用次数

举个例子:比如有5组数据要填充到listView。listView会先调用onMeasure,此时会调用5次getView。然后才调用onLayout,此时又会调用5次getView,这样就重复了。所以导致多次调用getView方法。

* 当ListView高度为wrap_content时:

<ListView
        android:id="@+id/listview"
        android:divider="#666666"
        android:dividerHeight="1px"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

如下图:

 Android ListView 优化之 getView 与 ViewHolder 是如何工作的?

这里牵扯一个问题,那就是布局优化的问题,如果我们将ListView的高度设置为wrap_content时ListView会去调用getView去动态计算高度,

这样的话导致ListView会再次调用getView去渲染视图。所以建议,将ListView的高度设置成一个固定的值或者match_parent,这样的话,会啊减少调用次数。

* 将ListView高度设置为match_parent时如下图:

<ListView
        android:id="@+id/listview"
        android:divider="#666666"
        android:dividerHeight="1px"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

 Android ListView 优化之 getView 与 ViewHolder 是如何工作的?

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:gravity="center"
        android:text="万能适配器测试"
        android:textColor="#000000"
        android:textSize="18sp" />
</LinearLayout>

2.getView到底加载了多少个item布局与创建了多少个ViewHolder?findViewById多少次?

 Android ListView 优化之 getView 与 ViewHolder 是如何工作的?

通过日志,我们发现,其实listView不是根据你设置的多少个item数据去加载布局,而是根据你手机的屏幕一屏能够

展示多少个item的数据(包括没有完全显示的item),也就是说

if (convertView == null) {
            convertView = LayoutInflater.from(context).inflate(R.layout.item, null);
            viewHolder = new ViewHolder();
            viewHolder.textView = (TextView) convertView.findViewById(R.id.textView);
            convertView.setTag(viewHolder);
        }

这段加载布局的代码只走了你手机一屏能显示的个数,也就是说创建了这么多的Viewholder,但你滑动到别的也没的时候会复用第一屏的item然后我们去改变item中的值。由此可以看出,ListView不管记载多少数据都不会OOM,因为ListView始终只加载了一屏的数据这正是ListView的强大之处。其复用原理如图:

 Android ListView 优化之 getView 与 ViewHolder 是如何工作的?
 
标签: ListView
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Android 自定义ListView adapter(zt)
    Android 自定义ListView adapter(zt)
    本文讲实现一个自定义列表的Android程序,程序将实现一个使用自定义的适配器(Adapter)绑定数据,通过contextView.setTag绑定数据有按钮的ListView。系统显示列表(ListView)时,首先会实例化一个适配器,本文将实例化一个自定义的适配器。实现自定义适配器
    12-01 ListView
  • listviewd优化---viewHolder的封装
    listviewd优化---viewHolder的封装
    android项目中如果使用listview控件,则在优化上我们一般使用viewHolder保证列表项的布局convertView可以被重用避免多次重新绘制。 一般方法中getView的写法@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder vie
    11-07 安卓开发
  • Android ListView优化之局部刷新(更新)(非notifyDataSetChanged)
    Android ListView优化之局部刷新(更新)(非no
    在Android开发中我们经常会用到listview的数据和界面刷新动作,我们每次可能会用到的都是Adapter.notifyDataSetChanged()方法。这个方法的原理是利用观察者模式对我们的数据源进行监听,当我们的数据源发生变化的时候,会调用Adapter的getView()方法进行整个
    11-04 ListView
  • 基础篇章:关于 React Native 之 ListView 组件的讲解
    基础篇章:关于 React Native 之 ListView 组件
    我们讲完ScrollView组件,其实顺其自然的就应该讲解ListView,对于前段和移动端的开发人员应该非常熟悉这样的控件吧,具体是做什么的,我感觉不用我讲了吧。我们来看看它怎么使用吧。大家好,我是ListView,我是React Native大家族中基础组件中,一个核心组件
  • Android ListView 使用不同对象加载不同布局
    Android ListView 使用不同对象加载不同布局
    因为未知原因,突然想到了关于一个 List 集合里面能否添加不同对象的问题,因为我们平时开发过程中,关于List 的比较常规的写法就是:ListXXX list = new ArrayListXXX();这让我形成了一种 List 里面就只能添加一种类型的对象的潜在想法(或许是 Java 基础不
    10-31 ListView
  • Android应用性能优化系列视图篇——ListView自适应导致的严重性能问题
    Android应用性能优化系列视图篇——ListView自
    ListView是Android中最常用的视图之一,使用的频率仅仅次于三大基础布局,虽然由于使用性和扩展性等原因备受争议,且尽管后来出现了RecyclerView的替代方案,但是ListView仍然广泛地使用在我们的项目中。自从ListView出道至今,已经不知道衍生出了多少问题,
  • android中listview的一些样式设置
    在 Android中,ListView是最常用的一个控件,在做UI设计的时候,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备一张图片然后指定属性 android:background=”@drawable/bg”,不过不要高兴地太早,当你这么做以后,发
    10-13 ListView
  • React Native填坑之旅--ListView篇
    列表显示数据,基本什么应用都是必须。笔者写作的时候RN版本是0.34。今天就来从浅到深的看看React Native的ListView怎么使用。首先是使用写死的数据,之后会使用网络请求的数据在界面中显示。最后加上一个ActivityIndicator,网络请求的过程中显示Loading图标
  • RecyclerView、ListView 实现单选列表的优雅之路.
    RecyclerView、ListView 实现单选列表的优雅之
    一 概述: 这篇文章需求来源还是比较简单的,但做的 优雅 仍有值得挖掘的地方。 需求来源:一个类似饿了么这种 电商优惠券的选择界面 : 其实就是 一个普通的列表,实现了 单选 功能,效果如图:(不要怪图渣了,我撸了四五遍,公司录出来的GIF就这么渣。。。
  • [原]判断Listview滑动到了最底部(且最后一个ite
    记录下代码:listView.setOnScrollListener(new AbsListView.OnScrollListener() {@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleIte
    09-14 ListView
点击排行