Android应用 开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过分页 的形式来展示数据,个人觉得这样会有更好的用户体验。因此,很多应用都是采用分批次加载的形式来获取用户所需的数据。例如:微博客户端可能会在用户滑动至 列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据。

下面通过一个Demo来展示ListView功能如何实现:该Demo通过在ListView列表的底部添加一个“查看更多...”按钮来加载新闻(模拟新闻客户端)分页数据。同时限定每次加载10条记录,但完全加载完数据后,就 把ListView列表底部视图“查看更多...”删除。假设加载的数据总数为 38 条记录。先看下该Demo工程的程序结构图:

listView 分页加载数据_android

其中包 com.andyidea.bean中News.java类是新闻实体类,包com.andyidea.listview中 paginationListViewActivity.java类是用来展示ListView列表。布局layout中包含三个布局文件,分别 为:list_item.xml , loadmore.xml , main.xml 。下面分别贴下源码:

layout中的 list_item.xml源码:


​01​

​<?​​​​xml​​​​version​​​​=​​​​"1.0"​​​​encoding​​​​=​​​​"utf-8"​​​​?>​


​02​

​<​​​​LinearLayout​


​03​

​​​​​xmlns:android​​​​=​​​​"http://schemas.android.com/apk/res/android"​


​04​

​​​​​android:layout_width​​​​=​​​​"fill_parent"​


​05​

​​​​​android:layout_height​​​​=​​​​"fill_parent"​


​06​

​​​​​android:orientation​​​​=​​​​"vertical"​​​​>​


​07​

​​​​​<​​​​TextView​


​08​

​​​​​android:id​​​​=​​​​"@+id/newstitle"​


​09​

​​​​​android:layout_width​​​​=​​​​"fill_parent"​


​10​

​​​​​android:layout_height​​​​=​​​​"wrap_content"​​​​/>​


​11​

​​​​​<​​​​TextView​


​12​

​​​​​android:id​​​​=​​​​"@+id/newscontent"​


​13​

​​​​​android:layout_width​​​​=​​​​"fill_parent"​


​14​

​​​​​android:layout_height​​​​=​​​​"wrap_content"​​​​/>​


​15​

​</​​​​LinearLayout​​​​>​


layout中loadmore.xml源码:


​01​

​<?​​​​xml​​​​version​​​​=​​​​"1.0"​​​​encoding​​​​=​​​​"utf-8"​​​​?>​


​02​

​<​​​​LinearLayout​


​03​

​​​​​xmlns:android​​​​=​​​​"http://schemas.android.com/apk/res/android"​


​04​

​​​​​android:layout_width​​​​=​​​​"fill_parent"​


​05​

​​​​​android:layout_height​​​​=​​​​"fill_parent"​​​​>​


​06​

​​​​​<​​​​Button​


​07​

​​​​​android:id​​​​=​​​​"@+id/loadMoreButton"​


​08​

​​​​​android:layout_width​​​​=​​​​"fill_parent"​


​09​

​​​​​android:layout_height​​​​=​​​​"wrap_content"​


​10​

​​​​​android:text​​​​=​​​​"查看更多..."​​​​/> ​


​11​

​</​​​​LinearLayout​​​​>​


layout中main.xml源码:


​01​

​<?​​​​xml​​​​version​​​​=​​​​"1.0"​​​​encoding​​​​=​​​​"utf-8"​​​​?>​


​02​

​<​​​​LinearLayout​​​​xmlns:android​​​​=​​​​"http://schemas.android.com/apk/res/android"​


​03​

​​​​​android:orientation​​​​=​​​​"vertical"​


​04​

​​​​​android:layout_width​​​​=​​​​"fill_parent"​


​05​

​​​​​android:layout_height​​​​=​​​​"fill_parent"​​​​>​


​06​

​​​​​<​​​​ListView​


​07​

​​​​​android:id​​​​=​​​​"@+id/lvNews"​


​08​

​​​​​android:layout_width​​​​=​​​​"fill_parent"​


​09​

​​​​​android:layout_height​​​​=​​​​"wrap_content"​​​​/>​


​10​

​</LinearLayou​


包 com.andyidea.bean中News.java类源码:


​01​

​package​​​​ com.andyidea.bean;​


​02​



​03​

​/**​


​04​

​​​​​* 新闻实体类​


​05​

​​​​​* @author Andy.Chen​


​06​

​​​​​* @mail Chenjunjun.ZJ@gmail.com​


​07​

​​​​​*​


​08​

​​​​​*/​


​09​

​public​​​​ class​​​​News {​


​10​



​11​

​​​​​private​​​​String title; ​​​​//标题​


​12​

​​​​​private​​​​String content; ​​​​//内容​


​13​



​14​

​​​​​public​​​​String getTitle() {​


​15​

​​​​​return​​​​title;​


​16​

​​​​​}​


​17​

​​​​​public​​​​void​​​​setTitle(String title) {​


​18​

​​​​​this​​​​.title = title;​


​19​

​​​​​}​


​20​

​​​​​public​​​​String getContent() {​


​21​

​​​​​return​​​​content;​


​22​

​​​​​}​


​23​

​​​​​public​​​​void​​​​setContent(String content) {​


​24​

​​​​​this​​​​.content = content;​


​25​

​​​​​}​


​26​



​27​

​}​


包com.andyidea.listview中paginationListViewActivity.java类源码:


​001​

​package​​​​ com.andyidea.listview;​


​002​



​003​

​import​​​​ java.util.ArrayList;​


​004​

​import​​​​ java.util.List;​


​005​



​006​

​import​​​​ com.andyidea.bean.News;​


​007​



​008​

​import​​​​ android.app.Activity;​


​009​

​import​​​​ android.os.Bundle;​


​010​

​import​​​​ android.os.Handler;​


​011​

​import​​​​ android.util.Log;​


​012​

​import​​​​ android.view.View;​


​013​

​import​​​​ android.view.ViewGroup;​


​014​

​import​​​​ android.widget.AbsListView;​


​015​

​import​​​​ android.widget.AbsListView.OnScrollListener;​


​016​

​import​​​​ android.widget.BaseAdapter;​


​017​

​import​​​​ android.widget.Button;​


​018​

​import​​​​ android.widget.ListView;​


​019​

​import​​​​ android.widget.TextView;​


​020​

​import​​​​ android.widget.Toast;​


​021​



​022​

​public​​​​ class​​​​PaginationListViewActivity ​​​​extends​​​​Activity ​​​​implements​​​​OnScrollListener {​


​023​



​024​

​​​​​private​​​​ListView listView; ​


​025​

​​​​​private​​​​int​​​​visibleLastIndex = ​​​​0​​​​; ​​​​//最后的可视项索引 ​


​026​

​​​​​private​​​​int​​​​visibleItemCount; ​​​​// 当前窗口可见项总数 ​


​027​

​​​​​private​​​​int​​​​datasize = ​​​​38​​​​; ​​​​//模拟数据集的条数​


​028​

​​​​​private​​​​PaginationAdapter adapter; ​


​029​

​​​​​private​​​​View loadMoreView; ​


​030​

​​​​​private​​​​Button loadMoreButton; ​


​031​

​​​​​private​​​​Handler handler = ​​​​new​​​​Handler(); ​


​032​



​033​

​​​​​/** Called when the activity is first created. */​


​034​

​​​​​@Override​


​035​

​​​​​public​​​​void​​​​onCreate(Bundle savedInstanceState) {​


​036​

​​​​​super​​​​.onCreate(savedInstanceState);​


​037​

​​​​​setContentView(R.layout.main);​


​038​



​039​

​​​​​loadMoreView = getLayoutInflater().inflate(R.layout.loadmore, ​​​​null​​​​);​


​040​

​​​​​loadMoreButton = (Button)loadMoreView.findViewById(R.id.loadMoreButton);​


​041​

​​​​​loadMoreButton.setOnClickListener(​​​​new​​​​View.OnClickListener() {​


​042​



​043​

​​​​​@Override​


​044​

​​​​​public​​​​void​​​​onClick(View v) {​


​045​

​​​​​loadMoreButton.setText(​​​​"正在加载中..."​​​​); ​​​​//设置按钮文字​


​046​

​​​​​handler.postDelayed(​​​​new​​​​Runnable() {​


​047​



​048​

​​​​​@Override​


​049​

​​​​​public​​​​void​​​​run() {​


​050​

​​​​​loadMoreData();​


​051​

​​​​​adapter.notifyDataSetChanged();​


​052​

​​​​​loadMoreButton.setText(​​​​"查看更多..."​​​​); ​​​​//恢复按钮文字​


​053​

​​​​​}​


​054​

​​​​​},​​​​2000​​​​);​


​055​



​056​

​​​​​}​


​057​

​​​​​});​


​058​



​059​

​​​​​listView = (ListView)findViewById(R.id.lvNews);​


​060​

​​​​​listView.addFooterView(loadMoreView); ​​​​//设置列表底部视图​


​061​

​​​​​initializeAdapter();​


​062​

​​​​​listView.setAdapter(adapter);​


​063​

​​​​​listView.setOnScrollListener(​​​​this​​​​);​


​064​

​​​​​}​


​065​



​066​

​​​​​@Override​


​067​

​​​​​public​​​​void​​​​onScrollStateChanged(AbsListView view, ​​​​int​​​​scrollState) {​


​068​

​​​​​int​​​​itemsLastIndex = adapter.getCount()-​​​​1​​​​; ​​​​//数据集最后一项的索引 ​


​069​

​​​​​int​​​​lastIndex = itemsLastIndex + ​​​​1​​​​;​


​070​

​​​​​if​​​​(scrollState == OnScrollListener.SCROLL_STATE_IDLE​


​071​

​​​​​&& visibleLastIndex == lastIndex) {​


​072​

​​​​​// 如果是自动加载,可以在这里放置异步加载数据的代码​


​073​

​​​​​}​


​074​

​​​​​}​


​075​



​076​



​077​

​​​​​@Override​


​078​

​​​​​public​​​​void​​​​onScroll(AbsListView view, ​​​​int​​​​firstVisibleItem,​


​079​

​​​​​int​​​​visibleItemCount, ​​​​int​​​​totalItemCount) {​


​080​

​​​​​this​​​​.visibleItemCount = visibleItemCount;​


​081​

​​​​​visibleLastIndex = firstVisibleItem + visibleItemCount - ​​​​1​​​​;​


​082​



​083​

​​​​​Log.e(​​​​"========================= "​​​​,​​​​"========================"​​​​);​


​084​

​​​​​Log.e(​​​​"firstVisibleItem = "​​​​,firstVisibleItem+​​​​""​​​​);​


​085​

​​​​​Log.e(​​​​"visibleItemCount = "​​​​,visibleItemCount+​​​​""​​​​);​


​086​

​​​​​Log.e(​​​​"totalItemCount = "​​​​,totalItemCount+​​​​""​​​​);​


​087​

​​​​​Log.e(​​​​"========================= "​​​​,​​​​"========================"​​​​);​


​088​



​089​

​​​​​//如果所有的记录选项等于数据集的条数,则移除列表底部视图​


​090​

​​​​​if​​​​(totalItemCount == datasize+​​​​1​​​​){​


​091​

​​​​​listView.removeFooterView(loadMoreView);​


​092​

​​​​​Toast.makeText(​​​​this​​​​, ​​​​"数据全部加载完!"​​​​, Toast.LENGTH_LONG).show();​


​093​

​​​​​}​


​094​

​​​​​}​


​095​



​096​

​​​​​/**​


​097​

​​​​​* 初始化ListView的适配器​


​098​

​​​​​*/​


​099​

​​​​​private​​​​void​​​​initializeAdapter(){​


​100​

​​​​​List<News> news = ​​​​new​​​​ArrayList<News>();​


​101​

​​​​​for​​​​(​​​​int​​​​i=​​​​1​​​​;i<=​​​​10​​​​;i++){​


​102​

​​​​​News items = ​​​​new​​​​News();​


​103​

​​​​​items.setTitle(​​​​"Title"​​​​+i);​


​104​

​​​​​items.setContent(​​​​"This is News Content"​​​​+i);​


​105​

​​​​​news.add(items);​


​106​

​​​​​}​


​107​

​​​​​adapter = ​​​​new​​​​PaginationAdapter(news);​


​108​

​​​​​}​


​109​



​110​

​​​​​/**​


​111​

​​​​​* 加载更多数据​


​112​

​​​​​*/​


​113​

​​​​​private​​​​void​​​​loadMoreData(){​


​114​

​​​​​int​​​​count = adapter.getCount();​


​115​



​116​

​​​​​if​​​​(count+​​​​10​​​​<= datasize){​


​117​

​​​​​for​​​​(​​​​int​​​​i=count+​​​​1​​​​; i<=count+​​​​10​​​​; i++){​


​118​

​​​​​News item = ​​​​new​​​​News();​


​119​

​​​​​item.setTitle(​​​​"Title"​​​​+i);​


​120​

​​​​​item.setContent(​​​​"This is News Content"​​​​+i);​


​121​

​​​​​adapter.addNewsItem(item);​


​122​

​​​​​}​


​123​

​​​​​}​​​​else​​​​{​


​124​

​​​​​for​​​​(​​​​int​​​​i=count+​​​​1​​​​; i<=datasize; i++){​


​125​

​​​​​News item = ​​​​new​​​​News();​


​126​

​​​​​item.setTitle(​​​​"Title"​​​​+i);​


​127​

​​​​​item.setContent(​​​​"This is News Content"​​​​+i);​


​128​

​​​​​adapter.addNewsItem(item);​


​129​

​​​​​}​


​130​

​​​​​}​


​131​



​132​

​​​​​}​


​133​



​134​



​135​

​​​​​class​​​​PaginationAdapter ​​​​extends​​​​BaseAdapter{​


​136​



​137​

​​​​​List<News> newsItems;​


​138​



​139​

​​​​​public​​​​PaginationAdapter(List<News> newsitems){​


​140​

​​​​​this​​​​.newsItems = newsitems;​


​141​

​​​​​}​


​142​



​143​

​​​​​@Override​


​144​

​​​​​public​​​​int​​​​getCount() {​


​145​

​​​​​return​​​​newsItems.size();​


​146​

​​​​​}​


​147​



​148​

​​​​​@Override​


​149​

​​​​​public​​​​Object getItem(​​​​int​​​​position) {​


​150​

​​​​​return​​​​newsItems.get(position);​


​151​

​​​​​}​


​152​



​153​

​​​​​@Override​


​154​

​​​​​public​​​​long​​​​getItemId(​​​​int​​​​position) {​


​155​

​​​​​return​​​​position;​


​156​

​​​​​}​


​157​



​158​

​​​​​@Override​


​159​

​​​​​public​​​​View getView(​​​​int​​​​position, View view, ViewGroup parent) {​


​160​

​​​​​if​​​​(view == ​​​​null​​​​){​


​161​

​​​​​view = getLayoutInflater().inflate(R.layout.list_item, ​​​​null​​​​);​


​162​

​​​​​}​


​163​



​164​

​​​​​//新闻标题​


​165​

​​​​​TextView tvTitle = (TextView)view.findViewById(R.id.newstitle);​


​166​

​​​​​tvTitle.setText(newsItems.get(position).getTitle());​


​167​

​​​​​//新闻内容​


​168​

​​​​​TextView tvContent = (TextView)view.findViewById(R.id.newscontent);​


​169​

​​​​​tvContent.setText(newsItems.get(position).getContent());​


​170​



​171​

​​​​​return​​​​view;​


​172​

​​​​​}​


​173​



​174​

​​​​​/**​


​175​

​​​​​* 添加数据列表项​


​176​

​​​​​* @param newsitem​


​177​

​​​​​*/​


​178​

​​​​​public​​​​void​​​​addNewsItem(News newsitem){​


​179​

​​​​​newsItems.add(newsitem);​


​180​

​​​​​}​


​181​



​182​

​​​​​}​


​183​



​184​

​}​



最后,运行程序的结果截图如下:

listView 分页加载数据_xml_02

通过上面的截图,当我们点击"查看更多..."按钮时,就会加载下10条记录,当加载完所有的记录后,ListView的底部视图将会移除。