• ListView缓存机制


    要想优化ListView首先要了解它的工作原理,列表的显示需要三个元素:ListView、Adapter、显示的数据;

    这里的Adapter就是用到了适配器模式,不管传入的是什么View在ListView中都能显示出来。

    下面简单说下上图的原理:

    1、如果你有几千几万甚至更多的选项(item)时,其中只有可见的项目(满屏显示的Item数目)存在内存(说的优化就是说在内存中的优化!)中,其他的在Recycler中

    2、ListView先请求一个type1视图(getView)然后请求其他可见的项目。convertView在getView中是空(null)的,第一次都是为空的,只要显示过了convertView都不为空,会保存在Recycler中

    3、当item1滚出屏幕,并且一个新的项目从屏幕低端上来时,ListView再请求一个type1视图。convertView此时不是空值 了,它的值是item1。你只需设定新的数据然后返回convertView,不必重新创建一个视图,省去了inflate和findViewById的 时间,性能就得到了优化。

    了解了它的工作原理后,我们就可以重复利用convertView,只要不为空就直接使用,改变它的内容就行了。

    使用ListView的时候都会搭配一个Adapter,为了使得性能更优,ListView会缓存行item(某行对应的View)。ListView通过Adapter的getView函数获得每行的item。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    package com.dzt.listviewdemo;
     
    import java.util.ArrayList;
     
    import android.app.Activity;
    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.ImageView;
    import android.widget.ListView;
    import android.widget.TextView;
     
    public class MainActivity extends Activity {
     
        private ListAdapter adapter;
        private ListView lv = null;
        private ArrayList<string> list = new ArrayList<string>();
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            lv = (ListView) findViewById(R.id.lv_list);
            adapter = new ListAdapter();
            for (int i = 0; i < 100; i++) {
                list.add(item  + i);
            }
            lv.setAdapter(adapter);
        }
     
        private class ListAdapter extends BaseAdapter {
     
            private LayoutInflater mInflater;
     
            ListAdapter() {
                mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            }
     
            @Override
            public int getCount() {
                // TODO Auto-generated method stub
                return list.size();
            }
     
            @Override
            public Object getItem(int position) {
                // TODO Auto-generated method stub
                return list.get(position);
            }
     
            @Override
            public long getItemId(int position) {
                // TODO Auto-generated method stub
                return position;
            }
     
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // TODO Auto-generated method stub
                System.out.println(getView  + position +      + convertView);
                viewHolder holder = null;
                if (convertView == null) {
                    convertView = mInflater.inflate(R.layout.item, null);
                    holder = new viewHolder();
                    holder.text = (TextView) convertView.findViewById(R.id.tv_text);
                    holder.image = (ImageView) convertView
                            .findViewById(R.id.iv_img);
                    convertView.setTag(holder);
                } else {
                    holder = (viewHolder) convertView.getTag();
                }
                holder.text.setText(list.get(position));
                if (position % 2 == 0) {
                    holder.image.setImageResource(R.drawable.ic_launcher);
                } else {
                    holder.image.setImageResource(R.drawable.icon);
                }
     
                return convertView;
            }
     
        }
     
        /**
         * 使用一个类来保存Item中的元素
         *
         * @author Administrator
         *
         */
        public static class viewHolder {
            public TextView text;
            public ImageView image;
        }
    }
    </string></string>

    运行效果


    第一次打印的结果convertView都是为null

    滑动ListView后的打印

    从上面的打印消息可以看出,Recycler中会保存七个convertView对象用来显示Item,不管你有上千个Item,也只会创建显示满屏的convertView,这就大大节省了内存,对viewHolder的Tag的使用也大大节省了性能开销

  • 相关阅读:
    [Error]错误 C2660: Gdiplus::GdiplusBase::operator new: 函数不带三个参数
    opengl多线程的问题
    去掉CFormView的滚动条
    DevIL库使用时图片翻转的问题
    让notepad++正确显示actionscript文件语法高亮
    [Error]world geometry is not supported by the generic scenemanager
    3d Max 9的"正在验证许可证"问题的解决
    CSizingControlBar Error C2440: “static_cast”: 无法从“UINT (__thiscall CSizingControlBarG::* )(CPoint)”转换为>>>
    MFC下的OpenGL
    酷!不用外挂,Win7资源监视器查看QQ好友IP
  • 原文地址:https://www.cnblogs.com/jasonxcj/p/5048989.html
Copyright © 2020-2023  润新知