Android中的延迟加载系列(ListView 1)
来源:互联网 发布:怀化学院教育网络系统 编辑:程序博客网 时间:2024/06/05 06:27
在Java语言开发中,大家对延迟加载并不陌生,比如Hibernate开发中就大量用到了延迟加载的技术。延迟加载在Android中同样适用,其基本思想是:只有在必要的时候,才去加载数据项。
本系列文章将对Android中常用的延迟加载进行简要的总结,并给出示例代码,以帮助读者的理解。由于时间的限制,本系列文章只讲解Android中的ListView和ImageView,其它涉及的组件较为类似,因此不一一展开。
在android开发中ListView是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。当需要从服务器获取大量数据的时候,为了节约用户的网络流量负载以及提高大数据量操作和显示的速度,这个时候往往需要用到延迟加载的技术。
ListView的延迟加载技术中,endless比较有名,大家可以到https://github.com/commonsguy/cwac-endless下载相应的jar,作为项目的类库。由于网上有很多endless相关的文章,因此本文不再累述。本文的主要目的是封装endless,寻找一种更加简易、清晰和可扩展的方式,以求达到对ListView的延迟加载。下文逐步阐述:
首先定义个延迟加载数据类(LazyListData.java),此类非常简单,抽象了List数据的总行数totalRows以及当前已有的行数据listData. List的数据类型通过<T>泛型(也可以用别的字母)的方式来定义。Serializable表示数据的可序列化。
- import java.util.List;
- public class LazyListData<T> implements java.io.Serializable{
- private static final long serialVersionUID = 296133151360323907L;
- private int totalRows;
- private List<T> listData;
- public LazyListData(int totalRows,List<T> listData){
- this.totalRows = totalRows;
- this.listData = listData;
- }
- public int getTotalRows() {
- return totalRows;
- }
- public void setTotalRows(int totalRows) {
- this.totalRows = totalRows;
- }
- public List<T> getListData() {
- return listData;
- }
- public void setListData(List<T> listData) {
- this.listData = listData;
- }
- }
import java.util.List;public class LazyListData<T> implements java.io.Serializable{private static final long serialVersionUID = 296133151360323907L;private int totalRows;private List<T> listData;public LazyListData(int totalRows,List<T> listData){this.totalRows = totalRows;this.listData = listData;}public int getTotalRows() {return totalRows;}public void setTotalRows(int totalRows) {this.totalRows = totalRows;}public List<T> getListData() {return listData;}public void setListData(List<T> listData) {this.listData = listData;}}
其次定义个延迟加载的接口(LazyLoading.java),此类抽象了获取下一页数据的方法以及获取数据后更新相应页面的方法。startIndex是下一页数据相对于整体数据的开始索引,endindex是下一页相对于整体数据数据的结束索引
- public interface LazyLoading{
- public void cacheNextPageData(int startIndex,int endIndex);
- public void updateItemView(View convertView, Object bean);
- }
public interface LazyLoading{public void cacheNextPageData(int startIndex,int endIndex);public void updateItemView(View convertView, Object bean);}
再次对EndlessAdapter进行封装(LazyAdapter.java),参见以下代码。
- package com.whyonly.wrapper;
- 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.ListView;
- import com.commonsware.cwac.endless.EndlessAdapter;
- import com.whyonly.R;
- import com.whyonly.wrapper.LazyAdapter.LazyLoading;
- public class LazyAdapter<T> extends EndlessAdapter{
- private static final String TAG = "LazyAdapter";
- private static final int PAGE_SIZE_LAZY = 20;
- private Context mContext;
- private int mItemResId;
- private int mStartIndex_nextPage = 0;
- private int mPageSize = 20;
- private int mTotalRows = 0;
- private LazyLoading mLazyLoading;
- private ListView mListView;
- public LazyAdapter(ListView listView,Context context,int itemResId,List<T> list,int pageSize,int totalRows,LazyLoading lazyLoading) {
- super(new MyArrayAdapter1<T>(context,itemResId,list,lazyLoading));
- Log.d(TAG,"LazyAdapter()");
- mListView = listView;
- mContext = context;
- mItemResId = itemResId;
- mStartIndex_nextPage = list.size();
- mPageSize = pageSize;
- mTotalRows = totalRows;
- mLazyLoading = lazyLoading;
- }
- public LazyAdapter(ListView listView,Context context,int itemResId,List<T> list,int totalRows,LazyLoading lazyLoading) {
- this(listView,context,itemResId,list,PAGE_SIZE_LAZY,totalRows,lazyLoading);
- }
- public LazyAdapter(Context context,int itemResId,List<T> list,int totalRows,LazyLoading lazyLoading) {
- this(null,context,itemResId,list,PAGE_SIZE_LAZY,totalRows,lazyLoading);
- }
- public interface LazyLoading{
- public void cacheNextPageData(int startIndex,int endIndex);
- public void updateItemView(View convertView, Object bean);
- }
- @Override
- protected View getPendingView(ViewGroup parent) {
- Log.d(TAG,"getPendingView()");
- LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View row=vi.inflate(R.layout.progressrow, null);
- if(mStartIndex_nextPage >= mTotalRows){//hidden the recycle
- row.findViewById(R.id.progressBar1).setVisibility(View.GONE);
- row.setVisibility(View.GONE);
- }
- return row;
- }
- @Override
- protected boolean cacheInBackground() {
- Log.d(TAG,"getWrappedAdapter().getCount()="+getWrappedAdapter().getCount()+",mTotalRows="+mTotalRows);
- if(getWrappedAdapter().getCount()<mTotalRows){
- int endIndex_nextPage = Math.min(mStartIndex_nextPage + mPageSize -1,mTotalRows-1);
- mLazyLoading.cacheNextPageData(mStartIndex_nextPage,endIndex_nextPage);
- mStartIndex_nextPage = endIndex_nextPage + 1;
- return true;
- }else{
- Log.d(TAG,"cacheInBackground() return false");
- return false;
- }
- }
- @Override
- protected void appendCachedData() {
- }
- }
- class MyArrayAdapter1<T> extends ArrayAdapter<T> {
- private Context mContext;
- private LazyLoading mLazyLoading;
- private int mItemResId;
- public MyArrayAdapter1(Context context, int itemResId, List<T> items,LazyLoading lazyLoading) {
- super(context, 0, items);
- this.mContext = context;
- mItemResId = itemResId;
- this.mLazyLoading = lazyLoading;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View item = convertView;
- if (item == null) {
- LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- item = vi.inflate(mItemResId, null);
- }
- final T bean = getItem(position);
- mLazyLoading.updateItemView(item, bean);
- return item;
- }
- }
package com.whyonly.wrapper;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.ListView;import com.commonsware.cwac.endless.EndlessAdapter;import com.whyonly.R;import com.whyonly.wrapper.LazyAdapter.LazyLoading;public class LazyAdapter<T> extends EndlessAdapter{private static final String TAG = "LazyAdapter";private static final int PAGE_SIZE_LAZY = 20;private Context mContext;private int mItemResId;private int mStartIndex_nextPage = 0;private int mPageSize = 20;private int mTotalRows = 0;private LazyLoading mLazyLoading;private ListView mListView;public LazyAdapter(ListView listView,Context context,int itemResId,List<T> list,int pageSize,int totalRows,LazyLoading lazyLoading) {super(new MyArrayAdapter1<T>(context,itemResId,list,lazyLoading));Log.d(TAG,"LazyAdapter()");mListView = listView;mContext = context;mItemResId = itemResId;mStartIndex_nextPage = list.size();mPageSize = pageSize;mTotalRows = totalRows;mLazyLoading = lazyLoading;}public LazyAdapter(ListView listView,Context context,int itemResId,List<T> list,int totalRows,LazyLoading lazyLoading) {this(listView,context,itemResId,list,PAGE_SIZE_LAZY,totalRows,lazyLoading);}public LazyAdapter(Context context,int itemResId,List<T> list,int totalRows,LazyLoading lazyLoading) {this(null,context,itemResId,list,PAGE_SIZE_LAZY,totalRows,lazyLoading);}public interface LazyLoading{public void cacheNextPageData(int startIndex,int endIndex);public void updateItemView(View convertView, Object bean);}@Overrideprotected View getPendingView(ViewGroup parent) {Log.d(TAG,"getPendingView()");LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);View row=vi.inflate(R.layout.progressrow, null);if(mStartIndex_nextPage >= mTotalRows){//hidden the recyclerow.findViewById(R.id.progressBar1).setVisibility(View.GONE);row.setVisibility(View.GONE);}return row;}@Overrideprotected boolean cacheInBackground() {Log.d(TAG,"getWrappedAdapter().getCount()="+getWrappedAdapter().getCount()+",mTotalRows="+mTotalRows);if(getWrappedAdapter().getCount()<mTotalRows){int endIndex_nextPage = Math.min(mStartIndex_nextPage + mPageSize -1,mTotalRows-1);mLazyLoading.cacheNextPageData(mStartIndex_nextPage,endIndex_nextPage);mStartIndex_nextPage = endIndex_nextPage + 1;return true;}else{Log.d(TAG,"cacheInBackground() return false");return false;}}@Overrideprotected void appendCachedData() {}}class MyArrayAdapter1<T> extends ArrayAdapter<T> { private Context mContext; private LazyLoading mLazyLoading;private int mItemResId;public MyArrayAdapter1(Context context, int itemResId, List<T> items,LazyLoading lazyLoading) { super(context, 0, items); this.mContext = context; mItemResId = itemResId; this.mLazyLoading = lazyLoading; }@Override public View getView(int position, View convertView, ViewGroup parent) { View item = convertView; if (item == null) { LayoutInflater vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); item = vi.inflate(mItemResId, null); } final T bean = getItem(position); mLazyLoading.updateItemView(item, bean); return item; }}
在此类中,R.layout.progressrow表示加载下一页代码的等待视图,等待视图的目的是提示用户正在加载,使得页面比较平滑和增加用户友好性,布局代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout android:id="@+id/linearLayout1"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:gravity="center"
- >
- <ProgressBar android:id="@+id/progressBar1" android:paddingTop="3dip"
- android:layout_width="wrap_content" android:layout_height="wrap_content"></ProgressBar>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?><LinearLayout android:id="@+id/linearLayout1"android:layout_width="fill_parent" android:layout_height="wrap_content"xmlns:android="http://schemas.android.com/apk/res/android"android:gravity="center"><ProgressBar android:id="@+id/progressBar1" android:paddingTop="3dip"android:layout_width="wrap_content" android:layout_height="wrap_content"></ProgressBar></LinearLayout>
至此,Listview延迟加载的封装基本结束,接下来将通过一个示例讲解如何在Activity中高效地应用此封装。(待续)
- Android中的延迟加载系列(ListView 1)
- Android中的延迟加载系列(ListView 1)
- Android中的延迟加载系列(ListView 2)
- Android中的延迟加载系列(ListView 2)
- Android中的延迟加载系列(ListView 3 含完整代码及工程下载)
- Android中的延迟加载系列(ListView 3 含完整代码及工程下载)
- Android中的延迟加载系列4(ImageView)
- Android中的延迟加载系列4(ImageView)
- Android中的延迟加载系列5 (综合案例 含完整代码及工程下载)
- Android中的延迟加载系列5 (综合案例 含完整代码及工程下载)
- android图片延迟加载,照片墙,listview中图片的延迟加载(国外制造)
- ListView异步延迟加载
- android viewpager中的fragment 延迟加载数据
- Android 延迟加载( AsynTask 异步加载)
- ibatis中的延迟加载(失效)
- Hibernate中的延迟加载
- Hibernate中的延迟加载
- js中的延迟加载
- 从头学习开发Django系列-自定义标签和过滤器
- 黑马程序员——交通灯管理系统
- 角谷步数 你听说过角谷猜想吗? 任意的正整数,比如 5, 我们从它开始,如下规则计算: 如果是偶数,则除以2,如果是奇数,则乘以3再加1. 如此循环,最终必会得到“1” !
- 关于c和c++中的eof函数多读一个问题
- Mysql之死锁解读
- Android中的延迟加载系列(ListView 1)
- Tomcat启动时遇到的异常问题
- [Python]小练习 -- 模拟登陆人人网
- POJ 1456 Supermarket
- 玩转SSRS第一篇---报表服务的配置
- android开发过程中涉及到的“概念”摘要
- 文件权限与目录
- Android中的延迟加载系列(ListView 2)
- UVa 784 Maze Exploration(DFS)