ListView优化分页优化
我们在用ListView展现数据的时候。比如展现联系人,如果联系人太多就会出现卡的现象,比如如果有1000多条数据,从数据库里查询,然后装载到List容器这段时间是比较耗时的。虽然我们可以用asyncTask来单独开启一个子线程加载。一次查看那么多,未免有点多余。是否可以通过先装载30条数据,如果用户需要我们在继续查询并且展示后面的数据,这样一来可以提升。使用速率。
实现方法
1、数据库分页查询
首先写SqlHelper指定每次查询数据库多少数据。代码如下
/**
* 分页查询黑名单
* 
* @param limit
* 限制数量
* @param offset
* 开始位置
* @return
*/
 public List<BlackNumInfo> getPartBlackNum(int limit, int offset)
 {
 //查询返回的数据容器
List<BlackNumInfo> blackNums = null; 
SQLiteDatabase db = dbHelper.getReadableDatabase();
String[] columns = new String[] { NUM, MODE, ID };
String selection = null; 
String[] selectionArgs = null;
String groupBy = null; 
String having = null;
String orderBy = null; // 排序功能
String limitsr = offset + "," + limit; // 分页数据
Cursor cursor = db.query(TABLE, columns, selection, selectionArgs, groupBy, having,
orderBy, limitsr);
 //如果没有数据就返回View
 if (cursor.getCount() > 0)
{
blackNums = new ArrayList<BlackNumInfo>();
}
 while (cursor.moveToNext())
{
String num = cursor.getString(0);
 int mode = cursor.getInt(1);
 int id = cursor.getInt(2);
BlackNumInfo b = new BlackNumInfo(num, mode, id);
blackNums.add(b);
}
db.close();
dbHelper.close();
 return blackNums;
}
2. AsyncTask类的内部优化
- 思路:每次开启一个异步任务查询数据。
 - 重置适配器中,数据容器的值,刷想适配器
 ListView重绘
/**
* 异步加载
*/
 public void fillData()
 {
 new AsyncTask<String, Integer, String>()
{
 // 程序运行前
 @Override
 protected void onPreExecute()
 {
mLoadProgressBar.setVisibility(View.VISIBLE);
 // 显示加载进度
 super.onPreExecute();
}
 // 程序运行时
 @Override
 protected String doInBackground(String... params)
 {
 // 查询 前30项的数据: 用子线程 ,
 if (mBlackNumList == null)
{
mBlackNumList = dao.getPartBlackNum(limit, offset);
} else
{
 // 如果不是第一次查询
 if (dao.getPartBlackNum(limit, offset) != null)
{
 //把查询到的数据添加到容器中去
mBlackNumList.addAll(dao.getPartBlackNum(limit, offset));
}
}
 return null;
}
 // 运行后
 @Override
 protected void onPostExecute(String result)
 {
 //ProgressBar设置为不可见。
mLoadProgressBar.setVisibility(View.INVISIBLE);
 if (adapter == null)
{
 //第一次加载,创建适配器适配器 
adapter = new BlackNumAdapter(context, mBlackNumList);
mBlackNumListView.setAdapter(adapter);
} else
{
 //第二次加载,适配器中容器数量
adapter.setBlackNumList(mBlackNumList);
 //发送通知,适配器内容改变,从新加载
adapter.notifyDataSetChanged();
}
}
}.execute();
}
3.Adapter优化分页数据
- 思路
 convertView可回收视图的再次利用。holderView类保存每次inflate出来View的子控件并保存在convertView的Tag中。- 添加一个
setDate()方法,重置容器数据 
public class BlackNumAdapter extends BaseAdapter
{
List<BlackNumInfo> mBlackNumList;
Context context;
BlackNumDao dao;
 public BlackNumAdapter(Context context, List<BlackNumInfo> mBlackNumList)
 {
 this.context = context;
dao = new BlackNumDao(context);
 this.mBlackNumList = mBlackNumList;
}
 public void setBlackNumList(List<BlackNumInfo> mBlackNumInfos)
 {
 this.mBlackNumList = mBlackNumInfos;
}
 @Override
 public int getCount()
 {
 return mBlackNumList.size();
}
 @Override
 public Object getItem(int position)
 {
 return mBlackNumList.get(position);
}
 @Override
 public long getItemId(int position)
 {
 return position;
}
 @Override
 public View getView(final int position, View convertView, ViewGroup parent)
 {
 // 适配器的优化
 final BlackNumInfo numInfo = mBlackNumList.get(position);
holderView hV = null;
 if (convertView == null)
{
hV = new holderView();
convertView = LayoutInflater.from(context).inflate(R.layout.item_blacknum, parent,
 false);
hV.modeTextView = (TextView) convertView.findViewById(R.id.tv_mode);
hV.numberTextView = (TextView) convertView.findViewById(R.id.tv_number);
hV.deleteImageView = (ImageView) convertView.findViewById(R.id.iv_deleteNumber);
convertView.setTag(hV);
} else
{
hV = (holderView) convertView.getTag();
}
hV.numberTextView.setText(mBlackNumList.get(position).getNum());
String mode = "全部拦截";
 switch (numInfo.getMode())
{
 case BlackNumDao.ALL:
mode = "全部链接";
 break;
 case BlackNumDao.CLL:
mode = "电话拦截";
 case BlackNumDao.SMS:
mode = "短信拦截";
 default:
 break;
}
hV.modeTextView.setText(mode);
hV.deleteImageView.setOnClickListener(new OnClickListener()
{
 @Override
 public void onClick(View v)
 {
 // 删除功能
dao.delete(numInfo.getNum() + "");
mBlackNumList.remove(position);
notifyDataSetChanged();
}
});
 return convertView;
}
}
/**
* 包装类
* @author H_lang
*
*/
class holderView
{
 public TextView modeTextView;
 public TextView numberTextView;
 public ImageView deleteImageView;
}
4.ListView滚动监听。
liseView设置滚动监听。- 重置
分页查询的开始标度 
 /**
* 滚动状态改变的时候。
*/
 @Override
 public void onScrollStateChanged(AbsListView view, int scrollState)
 {
 // 根据滚动的状态来加载数据。
 if (scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL)
{
 // 获得最后一次显示的数据
 int lastVisiblePosition = mBlackNumListView.getLastVisiblePosition();
 int size = mBlackNumList.size();
 if (lastVisiblePosition == size - 1)
{
 //设置下次查询的开始位置。
offset = limit + offset;
fillData();
}
}
}
总结
其中还是有许多的缺点。还有许多需要优化的功能。但是对于我现在学习的技术,没有想到更好的方法,希望以后我能继续优化,或者重写
listView控件。
ListView优化分页优化的更多相关文章
- 转-ListView的性能优化之convertView和viewHolder
		
ListView的性能优化之convertView和viewHolder 2014-05-14 参考:http://www.cnblogs.com/xiaowenji/archive/2010/12/ ...
 - mysql百万级分页优化
		
普通分页 数据分页在网页中十分多见,分页一般都是limit start,offset,然后根据页码page计算start , 这种分页在几十万的时候分页效率就会比较低了,MySQL需要从头开始一直往后 ...
 - 【MySQL】分页优化
		
前段时间由于项目的原因,对一个由于分页而造成性能较差的SQL进行优化,现在将优化过程中学习到关于分页优化的知识跟大家简单分享下. 分页不外乎limit,offset,在这两个关键字中,limit其实不 ...
 - MySQL 百万级分页优化
		
MySQL 百万级分页优化 http://www.jb51.net/article/31868.htm 一般刚开始学SQL的时候,会这样写 : , ; 但在数据达到百万级的时候,这样写会慢死 : , ...
 - 【Android】以BaseAdapter做适配器的ListView及其性能优化
		
适配器的Java类 package com.app.adapter; import org.json.JSONArray; import org.json.JSONObject; import and ...
 - ListView复用和优化详解
		
我们每一个Android开发人员对ListView的使用肯定是很熟悉的,然而多少人能真正的懂ListView的缓存机制呢,说白了就是ListView为了提高效率,而内部实现的一种优化,牺牲一点内存.而 ...
 - 使用Row_Number()分页优化
		
记一次SQLServer的分页优化兼谈谈使用Row_Number()分页存在的问题 最近有项目反应,在服务器CPU使用较高的时候,我们的事件查询页面非常的慢,查询几条记录竟然要4分钟甚至更长,而且 ...
 - MySQL分页优化中的“INNER JOIN方式优化分页算法”到底在什么情况下会生效?
		
本文出处:http://www.cnblogs.com/wy123/p/7003157.html 最近无意间看到一个MySQL分页优化的测试案例,并没有非常具体地说明测试场景的情况下,给出了一种经典的 ...
 - python全栈开发day58-mysql存储过程,权限,索引,慢日志,执行计划,分页优化处理
		
1.存储过程 delimiter // create procedure insert_data(in rows int) begin DECLARE n INT DEFAULT 1; drop ta ...
 
随机推荐
- win7重装系统的配置步骤
			
0. 关闭休眠功能,在开始菜单的运行里输入powercfg -h off 指令,关闭休眠,此文件实际大小和物理内存是一样的,大约可以为C盘释放1-3G的空间. 1. 在Win7桌面上显示“我的电脑” ...
 - Makefile自动生成头文件依赖
			
前言 Makefile自动生成头文件依赖是很常用的功能,本文的目的是想尽量详细说明其中的原理和过程. Makefile模板 首先给出一个本人在小项目中常用的Makefile模板,支持自动生成头文件依赖 ...
 - 从零开始学习jQuery
			
转自:http://www.cnblogs.com/zhangziqiu/archive/2009/04/30/jQuery-Learn-1.html 本系列文章导航 从零开始学习jQuery (一) ...
 - C#入门经典学习笔记一
			
这篇主要讲C#的一些语法. 1.委托 委托类型声明的格式如下: public delegate void TestDelegate(string message); delegate 关键字用于声明一 ...
 - bzoj 2618 2618: [Cqoi2006]凸多边形(半平面交)
			
2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 656 Solved: 340[Submit][Status] ...
 - UVA 10256  The Great Divide (凸包,多边形的位置关系)
			
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34148 [思路] 凸包 求出红蓝点的凸包,剩下的问题就是判断两个凸 ...
 - 《Linear Algebra and Its Applications》-chaper1-线性方程组- 线性变换
			
两个定理非常的简单显然,似乎是在证明矩阵代数中的基本运算律.但是它为后面用“线性变换”理解矩阵-向量积Ax奠定了理论基础. 结合之前我们讨论过的矩阵和向量的积Ax的性质,下面我们就可以引入线性变换了. ...
 - Codeforces 296C Greg and Array
			
数据结构题.个人认为是比较好的数据结构题.题意:给定一个长度为n的数组a,然后给定m个操作序列,每个操作:l, r, x将区间[l, r]内的元素都增加a,然后有k个查询,查询形式是对于操作序列x,y ...
 - Yii框架zii.widgets.grid自定义按钮,ajax触发事件并提示
			
相关类手册: http://www.yiichina.com/api/CButtonColumn buttons 属性 public array $buttons; the configurati ...
 - Yii PHP 框架分析(三)
			
作者:wdy http://hi.baidu.com/delphiss/blog/item/357663d152c0aa85a1ec9c44.html Yii应用的入口脚本引用出了Yii类,Yii类的 ...