Android ListView实现分页显示数据

分页加载优化ListView性能
本文介绍了如何在Android应用中实现分页加载ListView数据,以提高用户体验和性能。通过逐步加载数据,仅显示当前需要展示的内容,用户在滚动时动态加载更多数据,从而避免了一次性加载大量数据导致的卡顿现象。

当有大量的数据需要加载到ListView的Adapter中时,全部一次性加载,通常会非常耗时,这将严重影响用户的体验性和流畅性,而分页加载则会优化加载的速度,先暂时显示一页能够显示的数据项,在拖动到最下方时或点击了“显示更多”按钮时,再加载部分(需要自己定义每次显示多少)数据项。

而且此项技术,会在以后的运用中比较常用的使用到。


步骤一:设计主界面布局

mail.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <ListView  
  8.         android:id="@+id/listview"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         />  
  12.   
  13. </LinearLayout>   

为了测试,界面比较简单,就一个ListView。


步骤二:设计Adapter中每一项Item的布局

items.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <TextView  
  8.         android:id="@+id/bigtext"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:textSize="15pt"  
  12.         />  
  13.       
  14.     <TextView  
  15.         android:id="@+id/smalltext"  
  16.         android:layout_width="fill_parent"  
  17.         android:layout_height="wrap_content"  
  18.         android:layout_below="@id/bigtext"  
  19.         android:textSize="7pt"  
  20.         />  
  21.   
  22. </RelativeLayout>  

也是比较简单,就是两个TextView相对上下显示


步骤三:(重要)在Activity里设计代码

ShowItemsByPage.java

下面是定义的变量和onCreate函数

  1. <span style="white-space:pre">  </span>private ListView mListView = null;  
  2.     private SimpleAdapter adapter = null;  
  3.     private ArrayList<Map<String, String>> dataList = null;  
  4.     private final int maxShowItems = 100;   // 最多的加载项数目  
  5.     private final int stepShowItems = 10;   // 每次加载的数目  
  6.     private int lastShowItem = 0;           // 最后加载的项目  
  7.     private Handler mHanlder = null;        // 控制发布消息队列  
  8.       
  9.     /** Called when the activity is first created. */  
  10.     @Override  
  11.     public void onCreate(Bundle savedInstanceState) {  
  12.         super.onCreate(savedInstanceState);  
  13.         setContentView(R.layout.main);  
  14.           
  15.         mListView = (ListView)findViewById(R.id.listview);  
  16.         dataList = new ArrayList<Map<String, String>>();  
  17.         mHanlder = new Handler();  
  18.   
  19.         for(int i=0; i<10; i++)  
  20.         {  
  21.             HashMap<String, String> map = new HashMap<String, String>();  
  22.             map.put("big""大字体加载第" + i + "个选项");  
  23.             map.put("small""小字体加载第" + i + "个选项");  
  24.             dataList.add(map);  
  25.         }  
  26.           
  27.         // 设置ListView的Adapter  
  28.         adapter = new SimpleAdapter(this, dataList, R.layout.items, new String[]{"big""small"}, new int[]{R.id.bigtext, R.id.smalltext});  
  29.         mListView.setAdapter(adapter);  
  30.           
  31.         <strong><span style="color:#ff0000;">mListView.setOnScrollListener(new mOnScrollListener());</span></strong>  
  1. }  


在onCreate方法中,初始化了ListView、需要加载的ArrayList-->dataList、控制发送runnable消息的mHandler,

在for循环中,为了配合模拟器的显示,显式的要求初始时只先显示10个选项。

在for循环里,每次都定义一个HashMap对象,加载两个文本。


下面是loadData方法

  1. public void loaddata()  
  2.     {  
  3.         <span style="color:#ff0000;">int curCount = mListView.getAdapter().getCount();</span>  
  4.         Log.i("carter""当前Adapter的数量为: " + curCount);  
  5.           
  6.         <span style="color:#ff0000;">if( (curCount+stepShowItems)<=maxShowItems )</span>  
  7.         {  
  8.             <span style="color:#ff0000;">for(int i=curCount; i<(curCount+stepShowItems); i++)</span>  
  9.             {  
  10.                 HashMap<String, String> map = new HashMap<String, String>();  
  11.                 map.put("big""大字体加载第" + i + "个选项");  
  12.                 <span style="white-space:pre">  </span>map.put("small""小字体加载第" + i + "个选项");  
  13.                 <span style="white-space:pre">  </span>dataList.add(map);  
  14.             }  
  15.         }  
  16.         else  
  17.         {  
  18.             <span style="color:#ff0000;">for(int i=curCount; i<maxShowItems; i++)</span>  
  19.             {  
  20.                 HashMap<String, String> map = new HashMap<String, String>();  
  21.                 map.put("big""大字体加载第" + i + "个选项");  
  22.                 <span style="white-space:pre">  </span>map.put("small""小字体加载第" + i + "个选项");  
  23.                 <span style="white-space:pre">  </span>dataList.add(map);  
  24.             }  
  25.         }  
  26.     }  

这个函数主要是加载分页的数据项到ArrayList中

首先从Adapter中获取当前已经加载的数据项数目curCount,接下来的判断中,如果当前数据项curCount加上每次递进的数据项数目stepShowItems小于等于最大能加载的数据项数目maxShowItems,则把下一页的stepShowItems个数据项加入到ArrayList中,如果超过了maxShowItems,则只把剩余的几项加入到ArrayList中


下面是实现了android.widget.AbsListView.OnScrollListener接口的mOnScrollListener类

  1. private class mOnScrollListener implements OnScrollListener  
  2.     {  
  3.   
  4.         @Override  
  5.         public void onScroll(AbsListView view, int firstVisibleItem,  
  6.                 int visibleItemCount, int totalItemCount) {  
  7.             // TODO Auto-generated method stub  
  8.               
  9.             Log.i("carter""onScroll");  
  1. <span style="white-space:pre">          </span><span style="color:#ff0000;">//这里的算数逻辑可能有问题,请自行思考  
  2.             lastShowItem = firstVisibleItem + visibleItemCount;</span>  
  3.             Log.i("carter""lastShowItem = " + lastShowItem);  
  4.             Log.i("carter""visibleItemCount = " + visibleItemCount);  
  5.               
  6.             <span style="color:#ff0000;">if(lastShowItem == maxShowItems)</span>  
  7.             {  
  8.                 Toast.makeText(ShowItemsByPages.this"加载完成", Toast.LENGTH_SHORT).show();  
  9.             }  
  10.         }  
  11.   
  12.         @Override  
  13.         public void onScrollStateChanged(AbsListView view, int scrollState) {  
  14.             // TODO Auto-generated method stub  
  15.             Log.i("carter""onScrollStateChanged");  
  16.               
  17.             Log.i("carter""scrollState = " + scrollState);  
  18.             Log.i("carter""adapter count = " + mListView.getAdapter().getCount());  
  19.               
  20.             <span style="color:#ff0000;">if( (OnScrollListener.SCROLL_STATE_IDLE==scrollState) &&   
  21.                     (lastShowItem==(mListView.getAdapter().getCount())) )</span>  
  22.             {  
  23.                 ShowItemsByPages.this.mHanlder.post(new Runnable(){  
  24.                     public void run()  
  25.                     {  
  26.                     <span style="white-space:pre">  </span><span style="color:#ff0000;"><strong>ShowItemsByPages.this.loaddata();  
  27. <span style="white-space:pre">                  </span> ShowItemsByPages.this.adapter.notifyDataSetChanged();</strong></span>  
  28.                     }  
  29.                 });  
  30.             }  
  31.         }  
  32.     }  

mOnScrollListener实现了OnScrollListener接口,必须实现onScroll和onScrollStateChanged方法。

在onScroll方法中,通过方法自带的两个参数firstVisibleItem和visibleItemCount的和计算出当前显示的最后一个数据项lastShowItem,如果最后一个数据项等于最大能显示的数据项时,则说明已经全部加在完成了,弹出提示


在onScrollStateChanged方法中,主要完成拖动到列表最下方自动加在下一页数据项的功能。通过判断当前拖动的状态,和最后显示项和adapter显示项的判断,来确定是否加载下一页。如果可以加载,则用Handler的post一个Runnable到消息队列,通过loadData把数据项加载到ArrayList中,在通过Adapter的notifyDataSetChanged方法,重新加载数据项。


至此,就可以完成这个分页显示的功能了。

http://blog.youkuaiyun.com/carterjin/article/details/7508597
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值