Android应用开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过分页的形式来展示数据,个人觉得这样会有更好的用户体验。因此,很多应用都是采用分批次加载的形式来获取用户所需的数据。例如:微博客户端可能会在用户滑动至列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据。
下面通过一个Demo来展示ListView功能如何实现:该Demo通过在ListView列表的底部添加一个“查看更多...”按钮来加载新闻(模拟新闻客户端)分页数据。同时限定每次加载10条记录,但完全加载完数据后,就把ListView列表底部视图“查看更多...”删除。假设加载的数据总数为 38 条记录。先看下该Demo工程的程序结构图:
其中包 com.listviewpager中News.java类是新闻实体类,包com.listviewpager中 MainActivity.java类是用来展示ListView列表。布局layout中包含三个布局文件,分别为:list_item.xml , loadmore.xml , main_activity.xml 。下面分别贴下源码:
layout中的 list_item.xml源码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/newstitle"
android:textColor="@android:color/holo_purple"
android:textSize="20sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_margin="3dp"
android:textSize="20dp"
android:id="@+id/newscontent"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
layout中loadmore.xml源码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/loadMoreButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查看更多..." />
</LinearLayout>
layout中main_activity.xml源码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.listviewpager.MainActivity">
<ListView
android:id="@+id/lvNews"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.constraint.ConstraintLayout>
News.java类
源码:
package com.listviewpager;
/**
* Created by Administrator on 2016-08-01.
*/
public class News {
private String title;
private String content;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
MainActivity.java类
源码:
package com.listviewpager;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements AbsListView.OnScrollListener{
private ListView listView;
private int visibleLastIndex = 0; //最后的可视项索引
private int visibleItemCount; // 当前窗口可见项总数
private int datasize = 38; //模拟数据集的条数
private PaginationAdapter adapter;
private View loadMoreView;
private Button loadMoreButton;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadMoreView = getLayoutInflater().inflate(R.layout.loadmore,null);
loadMoreButton = (Button) loadMoreView.findViewById(R.id.loadMoreButton);
loadMoreButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
loadMoreButton.setText("正在加载中..."); //设置按钮文字
handler.postDelayed(new Runnable() {
@Override
public void run() {
loadMoreData();
adapter.notifyDataSetChanged();
loadMoreButton.setText("查看更多..."); //恢复按钮文字
}
},2000);
}
});
listView = (ListView) findViewById(R.id.lvNews);
listView.addFooterView(loadMoreView);
initializeAdapter();
listView.setAdapter(adapter);
listView.setOnScrollListener(this);
}
private void loadMoreData() {
int count = adapter.getCount();
if (count + 10 <= datasize) {
for (int i = 1; i <= 10; i++) {
News item = new News();
item.setTitle("helloworld" + i);
item.setContent("This is hello world" + i);
adapter.addNewsItem(item);
}
}else {
for (int i=count+1;i<=datasize;i++){
News item = new News();
item.setTitle("helloworld" + i);
item.setContent("This is hello world" + i);
adapter.addNewsItem(item);
}
}
}
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {
int itemsLastIndex = adapter.getCount()-1;
int lastIndex = itemsLastIndex+1;
if(i == AbsListView.OnScrollListener.SCROLL_STATE_IDLE && visibleLastIndex==lastIndex){
// 如果是自动加载,可以在这里放置异步加载数据的代码
}
}
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
this.visibleItemCount = i1;
visibleLastIndex = i + i1 - 1;
Log.e("========================= ","========================");
Log.e("firstVisibleItem = ",i+"");
Log.e("visibleItemCount = ",i1+"");
Log.e("totalItemCount = ",i2+"");
Log.e("========================= ","========================");
//如果所有的记录选项等于数据集的条数,则移除列表底部视图
if(i2 == datasize+1){
listView.removeFooterView(loadMoreView);
Toast.makeText(getApplicationContext(),"全部加载完毕。。。",Toast.LENGTH_SHORT).show();
}
}
/**
* 初始化ListView的适配器
*/
public void initializeAdapter(){
List<News> news = new ArrayList<News>();
for(int i =1;i<=10;i++){
News items = new News();
items.setTitle("helloworld"+i);
items.setContent("This is hello world" + i);
news.add(items);
}
adapter = new PaginationAdapter(news);
}
private class PaginationAdapter extends BaseAdapter{
List<News> newItems;
public PaginationAdapter(List<News> newItems) {
this.newItems = newItems;
}
@Override
public int getCount() {
return newItems.size();
}
@Override
public Object getItem(int i) {
return newItems.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view==null){
view = getLayoutInflater().inflate(R.layout.list_item, null);
}
//新闻标题
TextView tv_title = (TextView) view.findViewById(R.id.newstitle);
tv_title.setText(newItems.get(i).getTitle());
//新闻内容
TextView tv_content = (TextView) view.findViewById(R.id.newscontent);
tv_content.setText(newItems.get(i).getContent());
return view;
}
/**
* 添加数据列表项
* @param newsitem
*/
public void addNewsItem(News newsitem){
newItems.add(newsitem);
}
}
}
最后,运行程序的结果截图如下:
通过上面的截图,当我们点击"查看更多..."按钮时,就会加载下10条记录,当加载完所有的记录后,ListView的底部视图将会移除。