Android实战简易教程-第二十五枪(基于Baas的数据表查询下拉刷新和上拉加载实现!)

上一节我们实现了数据表的加载,但是,当数据表数据很多时,我们就要考虑数据的分页,这里我们选用了PullToRefreshListView控件,先看一下该控件的说明:

效果图: 

                               正在刷新                                                                       刷新后

      

一、导入Library

下载源码后(https://github.com/chrisbanes/Android-PullToRefresh),里面有个Library工程,添加工程到Eclipse中;

另外extras文件夹还有两个工程:PullToRefreshListFragment和PullToRefreshViewPager,由于我们的这个用不到他们的库文件,所以不必导入了;

二、实战

1、新建工程,添加Libray库到工程中

新建工程(try_PullToRefresh)后,右键-》Properties-》Android-》Add  选择上面的Library,然后就是这个样子的

2、重写activity_main.xml

XML内容为:

[html] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <!--     The PullToRefreshListView replaces a standard ListView widget. -->
  7. <com.handmark.pulltorefresh.library.PullToRefreshListView
  8. android:id="@+id/pull_refresh_list"
  9. android:layout_width="fill_parent"
  10. android:layout_height="fill_parent"
  11. android:cacheColorHint="#00000000"
  12. android:divider="#19000000"
  13. android:dividerHeight="4dp"
  14. android:fadingEdge="none"
  15. android:fastScrollEnabled="false"
  16. android:footerDividersEnabled="false"
  17. android:headerDividersEnabled="false"
  18. android:smoothScrollbar="true" />
  19. </LinearLayout>

其中中间那一大段<com.handmark.pull………………/>就是相当于ListView控件,用这段来代替原是ListView控件的代码

下面我们看一下具体怎么实现的。

先在数据表中插入数据:

然后看代码,MainActivity.java:

package com.bmob.pagingdemo;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.listener.FindListener;

import com.handmark.pulltorefresh.library.ILoadingLayout;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener2;
import com.handmark.pulltorefresh.library.PullToRefreshListView;

public class MainActivity extends Activity {

	PullToRefreshListView mPullToRefreshView;
	private ILoadingLayout loadingLayout;
	ListView mMsgListView;
	List<TestData> bankCards = new ArrayList<TestData>();// 数据list

	private static final int STATE_REFRESH = 0;// 下拉刷新
	private static final int STATE_MORE = 1;// 加载更多

	private int limit = 10; // 每页的数据是10条
	private int curPage = 0; // 当前页的编号,从0开始

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Bmob.initialize(this, "8f3ffb2658d8a3366a70a0b0ca0b71b2");// 初始化
		queryData(0, STATE_REFRESH);

		initListView();// 初始化ListView
	}

	private void initListView() {
		mPullToRefreshView = (PullToRefreshListView) findViewById(R.id.list);
		loadingLayout = mPullToRefreshView.getLoadingLayoutProxy();
		loadingLayout.setLastUpdatedLabel("");
		loadingLayout
				.setPullLabel(getString(R.string.pull_to_refresh_bottom_pull));// 下拉标签
		loadingLayout
				.setRefreshingLabel(getString(R.string.pull_to_refresh_bottom_refreshing));// 刷新标签
		loadingLayout
				.setReleaseLabel(getString(R.string.pull_to_refresh_bottom_release));// 释放标签
		// //滑动监听
		mPullToRefreshView.setOnScrollListener(new OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {

			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {

				if (firstVisibleItem == 0) {
					loadingLayout.setLastUpdatedLabel("");
					loadingLayout
							.setPullLabel(getString(R.string.pull_to_refresh_top_pull));
					loadingLayout
							.setRefreshingLabel(getString(R.string.pull_to_refresh_top_refreshing));
					loadingLayout
							.setReleaseLabel(getString(R.string.pull_to_refresh_top_release));
				} else if (firstVisibleItem + visibleItemCount + 1 == totalItemCount) {// 加载完毕
					loadingLayout.setLastUpdatedLabel("");
					loadingLayout
							.setPullLabel(getString(R.string.pull_to_refresh_bottom_pull));
					loadingLayout
							.setRefreshingLabel(getString(R.string.pull_to_refresh_bottom_refreshing));
					loadingLayout
							.setReleaseLabel(getString(R.string.pull_to_refresh_bottom_release));
				}
			}
		});

		// 下拉刷新监听
		mPullToRefreshView
				.setOnRefreshListener(new OnRefreshListener2<ListView>() {

					@Override
					public void onPullDownToRefresh(
							PullToRefreshBase<ListView> refreshView) {
						// 下拉刷新(从第一页开始装载数据)
						queryData(0, STATE_REFRESH);
					}

					@Override
					public void onPullUpToRefresh(
							PullToRefreshBase<ListView> refreshView) {
						// 上拉加载更多(加载下一页数据)
						queryData(curPage, STATE_MORE);
					}
				});

		mMsgListView = mPullToRefreshView.getRefreshableView();
		// 再设置adapter
		mMsgListView.setAdapter(new DeviceListAdapter(this));
	}

	/**
	 * 分页获取数据
	 *
	 * @param page
	 *            页码
	 * @param actionType
	 *            ListView的操作类型(下拉刷新、上拉加载更多)
	 */
	private void queryData(final int page, final int actionType) {
		Log.i("bmob", "pageN:" + page + " limit:" + limit + " actionType:"
				+ actionType);

		BmobQuery<TestData> query = new BmobQuery<TestData>();
		query.setLimit(limit); // 设置每页多少条数据
		query.setSkip(page * limit); // 从第几条数据开始,
		query.findObjects(this, new FindListener<TestData>() {

			@Override
			public void onSuccess(List<TestData> arg0) {
				// TODO Auto-generated method stub

				if (arg0.size() > 0) {//能加载到数据
					if (actionType == STATE_REFRESH) {
						// 当是下拉刷新操作时,将当前页的编号重置为0,并把bankCards清空,重新添加
						curPage = 0;
						bankCards.clear();
					}

					// 将本次查询的数据添加到bankCards中
					for (TestData td : arg0) {
						bankCards.add(td);
					}

					// 这里在每次加载完数据后,将当前页码+1,这样在上拉刷新的onPullUpToRefresh方法中就不需要操作curPage了
					curPage++;
					showToast("第" + (page + 1) + "页数据加载完成");
				} else if (actionType == STATE_MORE) {//数据加载完毕
					showToast("没有更多数据了");
				} else if (actionType == STATE_REFRESH) {//无数据
					showToast("没有数据");
				}
				mPullToRefreshView.onRefreshComplete();
			}

			@Override
			public void onError(int arg0, String arg1) {
				// TODO Auto-generated method stub
				showToast("查询失败:" + arg1);
				mPullToRefreshView.onRefreshComplete();
			}
		});
	}

	/**
	 * Adapter
	 *
	 * @author Administrator
	 *
	 */
	private class DeviceListAdapter extends BaseAdapter {

		Context context;

		public DeviceListAdapter(Context context) {
			this.context = context;
		}

		@Override
		public View getView(final int position, View convertView,
				ViewGroup parent) {
			ViewHolder holder = null;
			if (convertView == null) {

				convertView = LayoutInflater.from(context).inflate(
						R.layout.list_item_bankcard, null);
				holder = new ViewHolder();
				holder.tv_cardNumber = (TextView) convertView
						.findViewById(R.id.tv_cardNumber);
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}

			TestData td = (TestData) getItem(position);

			holder.tv_cardNumber.setText(td.getName());
			return convertView;
		}

		class ViewHolder {
			TextView tv_cardNumber;
		}

		@Override
		public int getCount() {
			return bankCards.size();
		}

		@Override
		public Object getItem(int position) {
			return bankCards.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

	}

	private void showToast(String msg) {
		Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
	}

}

TestData.java:

package com.bmob.pagingdemo;

import cn.bmob.v3.BmobObject;

public class TestData extends BmobObject {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

main.xml:

<LinearLayout 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:orientation="vertical" >

    <com.handmark.pulltorefresh.library.PullToRefreshListView
        xmlns:ptr="http://schemas.android.com/apk/res/com.bmob.pagingdemo"
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fadingEdge="none"
        android:fastScrollEnabled="false"
        android:smoothScrollbar="true"
        ptr:ptrMode="both" />

</LinearLayout>

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.bmob.pagingdemo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="14" />

    <uses-permission android:name="android.permission.INTERNET" /> <!-- 允许应用打开网络套接口 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

运行实例,下拉刷新:

上拉加载,每次加载10条数据:

本实例有个问题,初次进入时不能加载数据,必须下拉才能加载数据,请能找出问题的朋友联系我:291214603,多谢!

喜欢的朋友可以关注我!谢谢!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-16 00:52:13

Android实战简易教程-第二十五枪(基于Baas的数据表查询下拉刷新和上拉加载实现!)的相关文章

Android实战简易教程-第二十二枪(基于Baas的用户注册功能)

基于Baas实现用户的注册功能. 我们使用Bmob提供的API进行实战开发,首先在Bmob官网上下载SDK,然后将jar包拷入工程内. 创建应用,获取应用key: 1.main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:

Android实战简易教程-第二十八枪(Uri转String型实例)

接上一篇文章.我们能够轻易的获取所选图片的uri,那么我们考虑怎样将获取的uri转换成String型的地址呢? 接下来我们通过实例来研究.布局文件和上篇(二十七枪)一致,我们就不再列出,直接看MainActivity.java: package com.example.userphoto; import java.io.File; import android.app.Activity; import android.content.Intent; import android.database

Android实战简易教程-第十五枪(实现ListView中Button点击事件监听)

1.main.xml <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" androi

Android实战简易教程-第二十九枪(基于Face++实现年龄识别APP(一))

我们通过Face++提供的api和服务实现HowOld App的开发.首先我们实现图片的选择功能. 1.main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:la

Android实战简易教程-第二十六枪(基于ViewPager实现微信页面切换效果)

1.头部布局文件top.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp" an

Android实战简易教程-第二十八枪(基于Bmob实现头像图片设置和网络上传功能!)

上一篇我们介绍了怎样由uri转换成String ,本文就用到了上篇文章的方法.以下我们介绍一下怎样设置头像后将头像图片上传到云端的方法,本文基于Bmob提供的服务. 看一下代码:(布局文件和前两篇文章依然一样,不再提供) package com.example.userphoto; import java.io.File; import android.app.Activity; import android.content.Intent; import android.database.Cur

Android实战简易教程-第十六枪(LineChart实现数据趋势展示)

aChartEngine中的line Chart是线图,是数据显示的一种.首先我们要下载aChartEngine的jar包,然后导入到工程中. 直接看一下代码(部分注释): package com.yayun.linechart; import java.util.ArrayList; import java.util.List; import org.achartengine.ChartFactory; import org.achartengine.chart.PointStyle; imp

Android实战简易教程-第十八枪(ViewPager组件详解)

对于ViewPager组件我们知道: 1)ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类. 2)ViewPager类需要一个PagerAdapter适配器类给它提供数据. 3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用. 下面我们通过实例看一下ViewPager的使用. 一 实现V

Android实战简易教程-第十九枪(SwipeRefreshLayout下拉刷新使用实例)

我们来看SwipeRefreshLayout的具体用法,顾名思义此组件就是一个布局,只不过要注意的是此布局内只能有一个直接子View.其实通过文档我们可以知道SwipeRefreshLayout只不过是继承了ViewGroup. 查看文档,我们可以知道,在SwipRefreshLayout中存在一个接口,通过此接口我们可以监听滑动手势,其实使用此组件最重要的步骤就是实现此接口的onRefresh方法,在此方法中实现数据的更新操作.如下: 接口中的方法: 除了OnRefreshListener接口