Android ListView实现分页显示数据

来源:互联网 发布:月报表软件 编辑:程序博客网 时间:2024/06/04 18:51

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

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


步骤一:设计主界面布局

mail.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <ListView        android:id="@+id/listview"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        /></LinearLayout> 

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


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

items.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <TextView        android:id="@+id/bigtext"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:textSize="15pt"        />        <TextView        android:id="@+id/smalltext"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_below="@id/bigtext"        android:textSize="7pt"        /></RelativeLayout>

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


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

ShowItemsByPage.java

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

private ListView mListView = null;private SimpleAdapter adapter = null;private ArrayList<Map<String, String>> dataList = null;private final int maxShowItems = 100;// 最多的加载项数目private final int stepShowItems = 10;// 每次加载的数目private int lastShowItem = 0;// 最后加载的项目private Handler mHanlder = null;// 控制发布消息队列    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);                mListView = (ListView)findViewById(R.id.listview);        dataList = new ArrayList<Map<String, String>>();        mHanlder = new Handler();        for(int i=0; i<10; i++)        {        HashMap<String, String> map = new HashMap<String, String>();        map.put("big", "大字体加载第" + i + "个选项");        map.put("small", "小字体加载第" + i + "个选项");        dataList.add(map);        }                // 设置ListView的Adapter        adapter = new SimpleAdapter(this, dataList, R.layout.items, new String[]{"big", "small"}, new int[]{R.id.bigtext, R.id.smalltext});        mListView.setAdapter(adapter);                mListView.setOnScrollListener(new mOnScrollListener());
    }


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

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

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


下面是loadData方法

public void loaddata()    {    int curCount = mListView.getAdapter().getCount();    Log.i("carter", "当前Adapter的数量为: " + curCount);        if( (curCount+stepShowItems)<=maxShowItems )    {    for(int i=curCount; i<(curCount+stepShowItems); i++)    {    HashMap<String, String> map = new HashMap<String, String>();    map.put("big", "大字体加载第" + i + "个选项");            map.put("small", "小字体加载第" + i + "个选项");            dataList.add(map);    }    }    else    {    for(int i=curCount; i<maxShowItems; i++)    {    HashMap<String, String> map = new HashMap<String, String>();    map.put("big", "大字体加载第" + i + "个选项");            map.put("small", "小字体加载第" + i + "个选项");            dataList.add(map);    }    }    }

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

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


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

private class mOnScrollListener implements OnScrollListener    {@Overridepublic void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {// TODO Auto-generated method stubLog.i("carter", "onScroll");
//这里的算数逻辑可能有问题,请自行思考lastShowItem = firstVisibleItem + visibleItemCount;Log.i("carter", "lastShowItem = " + lastShowItem);Log.i("carter", "visibleItemCount = " + visibleItemCount);if(lastShowItem == maxShowItems){Toast.makeText(ShowItemsByPages.this, "加载完成", Toast.LENGTH_SHORT).show();}}@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState) {// TODO Auto-generated method stubLog.i("carter", "onScrollStateChanged");Log.i("carter", "scrollState = " + scrollState);Log.i("carter", "adapter count = " + mListView.getAdapter().getCount());if( (OnScrollListener.SCROLL_STATE_IDLE==scrollState) && (lastShowItem==(mListView.getAdapter().getCount())) ){ShowItemsByPages.this.mHanlder.post(new Runnable(){public void run(){ShowItemsByPages.this.loaddata(); ShowItemsByPages.this.adapter.notifyDataSetChanged();}});}}}

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

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


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


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


原创粉丝点击