listview优化


转载请标明出处: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;
         }
     }
}




  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值