代码中写了注释,这里就不做阐述。
先看一张效果图:
当滑动到视图底部,底部显示Loading状态,然后加载数据,数据加载完成,Loading消失,新的数据显示。对ListView滑动状态有一个监听,
Activity需继承接口:OnScrollListener。
下面附上源码:
MainActivity
- package com.listview.jasonlee.demo;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.AbsListView;
- import android.widget.BaseAdapter;
- import android.widget.ListView;
- import android.widget.TextView;
- import android.widget.Toast;
- import android.widget.AbsListView.OnScrollListener;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- public class MainActivity extends Activity implements OnScrollListener,
- OnItemClickListener {
- private ListView listView;
- private List<String> currentData;// 当前视图显示的数据
- private CustomAdapter customadapter;// 自定义适配器
- private View loadingView;// 加载视图的布局
- private int currentPage = 1;// 当前页,默认为1
- private int pageSize = 10;// 每页显示十条信息
- private int last_item_position;// 最后item的位置
- private boolean isLoading = false;// 是否加载过,控制加载次数
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- listView = (ListView) findViewById(R.id.lv_id);
- // 加载视图布局
- loadingView = LayoutInflater.from(this).inflate(
- R.layout.list_page_load, null);
- // 创建当前用于显示视图的数据
- currentData = RemoteDataUtil.createUpdateData(currentPage, pageSize);
- currentPage = currentPage + 1;
- // 添加底部加载视图
- listView.addFooterView(loadingView);
- // 初始化适配器
- customadapter = new CustomAdapter(currentData, this);
- listView.setAdapter(customadapter);
- // 滚动条监听
- listView.setOnScrollListener(this);
- // ListView监听
- listView.setOnItemClickListener(this);
- }
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- last_item_position = firstVisibleItem + visibleItemCount - 1;
- if (last_item_position == totalItemCount - 2) {// 这里控制当焦点落在某一个位置时,开始加载.
- // 当前是在第9个位置开始加载,改为totalItemCount-1
- // 则会在第10个位置开始加载
- /**
- * Loading 标记当前视图是否处于加载中,如果正在加载(isLoading=true)就不执行更新操作
- * 加载完成后isLoading=false,在 loadingHandler 中改变状态
- */
- if (!isLoading) {
- Toast.makeText(MainActivity.this, "第 " + currentPage + " 页",
- Toast.LENGTH_LONG).show();
- // 开启一个线程加载数据
- isLoading = true;
- RemoteDataUtil.setRemoteDataByPage(currentPage, pageSize,
- new LoadStateInterface() {
- @Override
- public void onLoadComplete(List<String> remotDate) {
- customadapter.addItem(remotDate);
- handler.sendEmptyMessage(0);
- }
- });
- };
- };
- // 当ListView没有FooterView时,添加FooterView(---loadingView---)
- if (listView.getFooterViewsCount() == 0) {
- listView.addFooterView(loadingView);
- }
- }
- Handler handler = new Handler(){
- public void handleMessage(android.os.Message msg) {
- // 更新
- customadapter.notifyDataSetChanged();
- // 删除FooterView
- listView.removeFooterView(loadingView);
- // 进入下一页,此时视图未加载.
- isLoading = false;
- //当前页自加
- currentPage = currentPage + 1;
- };
- };
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- // TODO Auto-generated method stub
- }
- }
CustomAdapter
- package com.listview.jasonlee.demo;
- import java.util.List;
- import android.content.Context;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.TextView;
- public class CustomAdapter extends BaseAdapter {
- private List<String> currentData;// 当前视图显示的数据
- private LayoutInflater inflater;
- public CustomAdapter() {
- super();
- // TODO Auto-generated constructor stub
- }
- public CustomAdapter(List<String> currentData, Context context) {
- super();
- this.currentData = currentData;
- inflater = LayoutInflater.from(context);
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return currentData.size();
- }
- @Override
- public Object getItem(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return position;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- View view = inflater.inflate(R.layout.list_page_item, null);
- TextView tv_content = (TextView) view.findViewById(R.id.tv_content);
- tv_content.setText(currentData.get(position));
- return view;
- }
- public void addItem(List<String> items){
- for(String item:items){
- currentData.add(item);
- }
- }
- }
LoadStateInterface
- package com.listview.jasonlee.demo;
- import java.util.List;
- public interface LoadStateInterface {
- /* 加载完成 */
- public void onLoadComplete(List<String> remotDate);
- }
RemoteDataUtil
- package com.listview.jasonlee.demo;
- import java.util.ArrayList;
- import java.util.List;
- public class RemoteDataUtil {
- /**
- * @param currentPage
- * @param pageSize
- * @return
- * 模拟网络数据
- */
- public static List<String> createUpdateData(int currentPage, int pageSize) {
- List<String> list = new ArrayList<String>();
- for (int i = (currentPage - 1) * pageSize; i < currentPage * pageSize; i++) {
- list.add((i + 1) + ". 走在风中,今天阳光突然很温柔.");
- }
- return list;
- }
- // 模拟联接网络以及从网络中获取数据花费的时间
- public static void setRemoteDataByPage(final int currentPage,final int pageSize,final LoadStateInterface onLoadComplete) {
- new Thread(){
- @Override
- public void run() {
- // TODO Auto-generated method stub
- super.run();
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- // 获取当前要更新的数据
- List<String> updateDataList = createUpdateData(
- currentPage, pageSize);
- // 需要更新的数据加入当前数据集合
- onLoadComplete.onLoadComplete(updateDataList);
- }
- }.start();
- }
- }
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:id="@+id/main_layout"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <ListView android:id="@+id/lv_id"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
list_page_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="fill_parent"
- android:layout_height="fill_parent">
- <TextView
- android:id="@+id/tv_content"
- android:layout_width="fill_parent"
- android:layout_height="80dp"
- android:textSize="9pt"
- android:gravity="center_vertical"
- />
- </LinearLayout>
list_page_load.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/loading_layout"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical"
- android:gravity="center_horizontal"
- >
- <RelativeLayout
- android:id="@+id/load_id"
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:gravity="center_vertical"
- android:text="Loading..."
- android:textSize="12pt" />
- <ProgressBar android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:layout_alignParentRight="true"/>
- </RelativeLayout>
- </LinearLayout>