listview优化

来源:互联网 发布:唱歌视频录制软件 编辑:程序博客网 时间:2024/06/10 16:53


转载请标明出处:http://blog.csdn.net/qq1940879801/article/details/50240223


前一篇介绍listview原理,这篇接着讲listview优化


优化一:复用convertView

Listview自身考虑了优化的问题,在复写的Adapter类中,主要复写getCount()和getView()。界面上有多少条item显示,就会调用多少次的getView()方法。因此如果在每次调用的时候,如果不进行优化,每次都会使用LayoutInflate.from(context).infate(..),将xml文件解析,并显示在界面上,这是非常消耗资源的。因为有新的内容产生就需要产生新的view来存放并销毁旧的view,所以,可以复用旧的view用来存放新的内容。


优化二:缓存item条目的引用-----ViewHolder

findViewById()这个方法是比较耗性能的操作。
findViewById()原理:从最顶端的节点进行一层一层的解析,找到后再一层一层的返回,如果在左边没找到,就会接着解析右边,并进行相应的查询,直到找到位置。因此可以对findViewById进行优化处理。xml文件被解析的时候,只要被创建出来了,其孩子的id就不会改变。根据这个特点,可以将孩子id存入到指定的集合中,每次就可以直接取出集合中对应的元素就可以了。

优化三:listview中数据的分批及分页加载

假如listview有几十万条数据要显示,如果将几十万条数据直接加载到内存,是很消耗内存,怎么办?
先获取一些数据显示在界面上,以后每次只获取一些数据并显示在界面,实现分页显示


优化四:滑动的时候不加载数据,滑动停止才开始加载数据。
使用map存储之前使用过的数据,对数据进行复用并防止item错位

在src/包名新建FruitAdapter类

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
import java.util.HashMap;
import java.util.List;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.example.listviewtext.R;
import com.example.listviewtext.bean.Fruit;
/**
 * @ClassName: FruitAdapter
 * @Description: TODO 
 * @Author: Jesse
 * @Date: 2015-12-9 下午8:51:26
 * @Copyright: 2015 Jesse Inc. All rights reserved.
 */
public class FruitAdapter extends ArrayAdapter<Fruit> {
    private Context mContext;
    private int resourseId;
    /** 判断是否是初始化 */
    public boolean isInit = false;
    /** 缓存数据 */
    public HashMap<Integer, String> map = new HashMap<Integer, String>();
 
    public FruitAdapter(Context context, int resource, List<Fruit> objects) {
        super(context, resource, objects);
        mContext = context;
        resourseId = resource;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(resourseId,
                    null);
            viewHolder = new ViewHolder();
            viewHolder.tv_url = (TextView) convertView
                    .findViewById(R.id.tv_url);
            viewHolder.tv_name = (TextView) convertView
                    .findViewById(R.id.tv_name);
            convertView.setTag(viewHolder);
        else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.tv_url.setTag(position);// 设置tag标签,配合map进行复用并解决错位
        Fruit fruit = getItem(position);
        viewHolder.tv_name.setText(fruit.getName());
        /** 加载图片默认没滑动 */
        if (!isInit) {
            map.put(position, fruit.getIndex());
            viewHolder.tv_url.setText(fruit.getIndex());
            Log.d("adapter""fruit.getIndex()=" + fruit.getIndex());
        }
        Log.e("TAG""position=" + position);
        return convertView;
    }
 
    class ViewHolder {
        TextView tv_url;
        TextView tv_name;
    }
}


FirstActivity类
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
99
100
101
102
103
104
105
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.util.Log;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.TextView;
import com.example.listviewtext.R;
import com.example.listviewtext.adapter.FruitAdapter;
import com.example.listviewtext.bean.Fruit;
import com.jesse.base.BaseActivity;
 
/**
 * @ClassName: FirstActivity
 * @Description: TODO
 * @Author: Jesse
 * @Date: 2015-12-6 下午4:23:08
 * @Copyright: 2015 Jesse Inc. All rights reserved.
 */
public class FirstActivity extends BaseActivity implements OnScrollListener {
    /** 初始化存储数据 */
    private List<Fruit> fruits;
    /** 列表显示第一个可见对应item的位置,列表显示最后一个可见对应item的位置 */
    private int start_index, end_index;
    private FruitAdapter fruitAdapter;
    private ListView lv_fruit;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
 
    @Override
    protected int initLayout() {
        return R.layout.aty_main;
    }
 
    @Override
    protected void initData() {
        fruits = new ArrayList<Fruit>();
        for (int i = 0; i < 40; i++) {
            fruits.add(new Fruit("www.jesse.com\\" + i, "qq" + i));
        }
    }
 
    @Override
    protected void initView() {
        lv_fruit = (ListView) findViewById(R.id.lv_fruit);
        fruitAdapter = new FruitAdapter(this, R.layout.item_fruit, fruits);
        lv_fruit.setAdapter(fruitAdapter);
    }
 
    @Override
    protected void addListen() {
        lv_fruit.setOnScrollListener(this);
    }
 
    /**
     * 滑动状态改变的时候调用 scrollState值: 当屏幕停止滚动时为SCROLL_STATE_IDLE = 0;
     * 当屏幕滚动且用户使用的触碰或手指还在屏幕上时为SCROLL_STATE_TOUCH_SCROLL = 1;
     * 由于用户的操作,屏幕产生惯性滑动时为SCROLL_STATE_FLING = 2
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        Log.e("TAG""scrollState=" + scrollState);
        fruitAdapter.isInit = true;
        switch (scrollState) {
        case OnScrollListener.SCROLL_STATE_IDLE:// listview滑动停止
            for (; start_index < end_index; start_index++) {
                /** 通过tag标签获取 */
                TextView tv_url = (TextView) lv_fruit
                        .findViewWithTag(start_index);
                /** 通过缓存获取数据 */
                String str = fruitAdapter.map.get(start_index);
                if (str != null) {
                    tv_url.setText(str);
                    Log.d("First""str=" + str);
                else {
                    fruitAdapter.map.put(start_index, fruits.get(start_index)
                            .getIndex());
tv_url.setText("");
                    tv_url.setText("" + fruits.get(start_index).getIndex());
                    Log.d("First""start_index=" + start_index);
                }
 
            }
            break;
        }
    }
 
    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        Log.e("TAG""firstVisibleItem=" + firstVisibleItem
                "\n,visibleItemCount=" + visibleItemCount
                "\n,totalItemCount=" + totalItemCount);
        /** 设置当前屏幕显示的起始index和结束index */
        start_index = firstVisibleItem;
        end_index = firstVisibleItem + visibleItemCount;
        /** listview最后一个item */
        if (end_index >= totalItemCount) {
            end_index = totalItemCount;
        }
    }
}


demo下载:http://download.csdn.net/detail/qq1940879801/9342251


1 0
原创粉丝点击