ListView分页加载数据
2016-06-16 08:04
330 查看
ListView分页加载数据
ListView分页加载 在Android中是一个经常用到的技术,当我们需要加载大量的数据到列表显示时,假如一次性把所有数据加载完毕,可能会导致整个ListView列表卡顿,给用户的体验也非常不好。因而,我们可以将数据分为多次加载,每次加载其中的一部分,用户有需求的时候再加载其他部分,这样的设计会更加友好。ListView分页原理
在日常开发中,我们可能会遇到以下两种情况:服务器支持分页请求,简单地说,比如,我们总共要请求100条数据,服务器支持我们每次请求N条数据,我们可以分100 / N 次请求完成,并且这些数据有一定的顺序,我们想请求第几页的数据就可以请求第几页的数据(这种情况下,我们可以实现真正的分页加载数据)。
服务器不支持分布请求,我们没办法请求指定页的数据,只能一次性请求所有数据(这种情况下,我们只能自己处理,每次加载相应数目数据到ListView中)。
那么ListView分页原理就是,我们不一次性加载所有的数据,每次加载N条,然后我们监听ListView的滚动事件,当ListView滚动到最底部时,判定当前是否已加载完所有数据,如果未加载完毕,请求新一页的数据,直至所有的数据加载完成。
Demo实现
一般情况下,我们需要请求服务器的数据,但是这里我们只是要达到ListView分页加载的效果,我们自己模拟数据加载过程。首先是我们的主页面MainActivity,其对应的页面文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.hotzhi.listviewtest.MainActivity"> <ListView android:id="@+id/lv_data" android:layout_width="match_parent" android:layout_height="match_parent" android:fastScrollEnabled="false" android:smoothScrollbar="true" android:cacheColorHint="#00000000" android:divider="#ffcccccc" android:dividerHeight="0.2dp" /> </RelativeLayout>
这里没啥好介绍的,就只是一个ListView。接下来是,我们将ListView拖动到底部时,如果要加载新的数据,那么我们可以添加一个footerView,以更好的提示用户,下面是其布局文件,foot_view.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:baselineAligned="true" android:gravity="center|center_vertical" android:orientation="horizontal" android:paddingBottom="15dp" android:paddingTop="15dp" > <ProgressBar android:id="@+id/progressBar_id" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="center" style="?android:attr/progressBarStyleSmall" android:paddingBottom="2dp" android:paddingTop="2dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:gravity="center" android:text="加载更多中……" android:textSize="13sp" /> </LinearLayout> </FrameLayout>
也非常简单,就一个加载框,然后一个提示文本。
下面就是我们的具体实现了,MainActivity.java
package com.hotzhi.listviewtest; import android.os.Bundle; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.LayoutInflater; import android.widget.AbsListView; import android.widget.ArrayAdapter; import android.widget.FrameLayout; import android.widget.ListView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { /** 列表翻页每页加载数目 */ private static final int ONE_PAGE_ITEM_COUNT = 20; // 由于这里是测试数据,我们自己控制所有数据请求的结束位置,也就是页数达到MAX_PAGE无法再次请求数据。 /** 最大页数(测试) */ private static final int MAX_PAGE = 8; private List<String> lstData = new ArrayList<>(); private ArrayAdapter<String> mAdapter; private ListView lvData; /** 当前页码 */ public int iCurPageIndex = 0; /** 列表第一项 */ private int firstItem; /** 列表可见项 */ private int visibleItem; /** 列表可见项 */ private int totalItem; /** 是否可以上拉 */ private boolean canUpPull = true; /** 是否正在加载 */ private boolean isLoading = false; /** 页脚布局 */ private FrameLayout mFooterView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViews(); setListeners(); initData(); } private void findViews() { lvData = (ListView) findViewById(R.id.lv_data); mFooterView = (FrameLayout) LayoutInflater.from(this).inflate(R.layout.foot_view, null); } private void setListeners() { lvData.setOnScrollListener(onScrollListener); } private void initData() { requestData(); } /** * ListView滚动监听器 */ private AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (firstItem + visibleItem == totalItem) { // 当前处于不可上拉加载状态,不可继续请求数据 if(!canUpPull) { return ; } // 数据正在加载,不可继续请求 if(isLoading) { return ; } lvData.addFooterView(mFooterView); lvData.setSelection(lvData.getBottom()); isLoading = true; iCurPageIndex++; requestData(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { firstItem = firstVisibleItem; visibleItem = visibleItemCount; totalItem = totalItemCount; } }; /** * 请求加载更多数据 * 如,请求服务器数据 */ private void requestData() { // 这里我们休眠3秒钟,相当于3秒钟后数据才加载完毕 // 当然我们在实际项目中可能不需要休眠处理,直接请求数据等待数据返回即可。 new Thread() { public void run() { try { Thread.sleep(3000); // 主线程中加载数据 handler.sendEmptyMessage(0); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } private android.os.Handler handler = new android.os.Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); // 加载数据 // 加载第iCurPageIndex页数据 for(int i = iCurPageIndex * ONE_PAGE_ITEM_COUNT; i < (iCurPageIndex + 1) * ONE_PAGE_ITEM_COUNT; i++) { lstData.add("第" + i + "条数据"); } // 数据加载完毕设置相应标志 isLoading = false; canUpPull = true; lvData.removeFooterView(mFooterView); // 这里我们通过判断加载页位置与最大可加载页比较判断,是否已加载完所有数据 if(iCurPageIndex >= MAX_PAGE) { canUpPull = false; if(iCurPageIndex > 0) { Toast.makeText(MainActivity.this, "已到达最后一页!", Toast.LENGTH_SHORT).show(); } } if(mAdapter == null) { mAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, lstData); lvData.setAdapter(mAdapter); } else { mAdapter.notifyDataSetChanged(); } } }; }
相关文章推荐
- 完美实现Android ListView中的TextView的跑马灯效果
- android上改变listView的选中颜色
- more、less 和 most 的区别
- AJAX实现瀑布流触发分页与分页触发瀑布流的方法
- Delphi7中Listview的常用功能汇总
- Delphi控件ListView的属性及使用方法详解
- 十万条Access数据表分页的两个解决方法
- sqlserver关于分页存储过程的优化【让数据库按我们的意思执行查询计划】
- 高效的mysql分页方法及原理
- asp又一个分页的代码例子
- SqlServer 2000、2005分页存储过程整理第1/3页
- JQuery的Pager分页器实现代码
- ADO存取数据库时如何分页显示
- 透彻掌握ASP分页技术很详细的分析
- jQuery实现的简单分页示例
- Android ListView弹性效果的实现方法
- android中ListView数据刷新时的同步方法
- Android提高之ListView实现自适应表格的方法
- Android中实现水平滑动(横向滑动)ListView示例
- Android ListView分页功能实现方法