您的位置:首页 > 移动开发 > Android开发

赵雅智_android实例_当监听类有数据更新时下拉刷新

zhaoyazhi2129 2014-06-11 17:59 46 查看
之前两篇文章分别介绍了OnScrollListener的实现和ContentProvider监听数据的变化,下面我们就结合者两个知识点实现一个小项目

项目需求

使用当ContentProvider监听类有数据更新时,在当前界面进行提示,并用OnScrollListener实现下拉刷新

实现效果

通过ContentProvider显示数据在界面



当监听类发生变化时



下拉刷新后显示数据



实现步骤

android_sqlite项目

定义操作标识
匹配结果码
继承ContentProvider类重写方法

oncreate初始化数据DatabaseHelper
getType

返回操作的类型 如果操作多条记录那么MINE类型vnd.android.cursor.dir/开头
如果操作的数据只有一条记录那么MINE类型vnd.android.cursor.item/开头

insert

匹配uri
插入操作
监听数据变化

update

匹配多条数据还是1条数据
更新操作
监听数据变化

query

匹配多条数据还是1条数据
查询操作

delete

匹配多条数据还是1条数据
删除操作
监听数据变化

android_providers项目

获取控件对象

listView
tv_tip,tv_name,tv_phone

获取内容解析器对象
初始化数据

通过内容解析器对象执行查询
设置adapter

注册监听器

新建class继承ContentObserver类

绑定handler对象

根据请求处理数据

重写onChange(booleab selfChange)方法发送handler的message消息

实现OnScrollListener接口并实现方法

onScroll
onScrollStateChanged

初始化数据
隐藏tip

重点代码:

android_sqlite项目中的UserContentProviders类

package com.example.android_sqlite.provider;

import com.example.android_sqlite.database.DatabaseHelper;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

public class UserContentProviders extends ContentProvider {
	// 操作的标志
	private static final String AUTHORITIE = "www.csdn.com.provider.userContentProvider";
	// 定义uri解析返回的匹配码
	private static final int USERCODE = 1;
	private static final int USERSCODE = 2;

	private static UriMatcher uriMatcher;

	private String USERS_DIR = "vnd.android.cursor.dir/users";
	private String USERS_ITEM = "vnd.android.cursor.item/users";

	private DatabaseHelper dh;
	static {
		// 实例化UriMatcher对象
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		// 匹配的结果码
		uriMatcher.addURI(AUTHORITIE, "users", USERSCODE);
		uriMatcher.addURI(AUTHORITIE, "users/#", USERCODE);
	}

	/**
	 * 在UserContentProvider创建之后,就会被调用,当其他应用程序第一次访问contentPrivider时,
	 * 该ContentProvider就会被创建出来
	 */
	@Override
	public boolean onCreate() {
		dh = new DatabaseHelper(getContext());
		return false;
	}

	/**
	 * URL:http://www.baidu.com/index.html http://: http协议访问网站
	 * www.baidu.com:域名部分 /index.html:网站资源
	 * 
	 * URI:content://www.csdn.com.provider.userContentProvider/user
	 * content://android的ContentProvider的规定
	 * www.csdn.com.provider.userContentProvider:文件汇中自己配置的authorities
	 * user:资源部分(数据部分)当访问者需要访问不同的资源时,这个部分是动态改变.这个部分可以自己定义
	 * 
	 * UriMatcher:匹配uri
	 */
	/**
	 * 查询方法
	 */
	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		SQLiteDatabase db = dh.getWritableDatabase();
		Cursor c = null;
		switch ((uriMatcher.match(uri))) {
		case USERCODE:// 一个条目
			long id = ContentUris.parseId(uri);
			c = db.query("users", projection, "userid=?", new String[] { id
					+ "" }, null, null, sortOrder);
			break;
		case USERSCODE:
			c = db.query("users", projection, selection, selectionArgs, null,
					null, sortOrder);
			break;
		default:
			throw new IllegalArgumentException("unknow URI" + uri);
		}
		return c;
	}

	/**
	 * 返回操作的类型 如果操作多条记录那么MINE类型vnd.android.cursor.div/开头
	 * 如果操作的数据只有一条记录那么MINE类型vnd.android.cursor.item/开头
	 */
	@Override
	public String getType(Uri uri) {
		String value = null;
		switch (uriMatcher.match(uri)) {
		case USERCODE:
			value = USERS_ITEM;
			break;
		case USERSCODE:
			value = USERS_DIR;
			break;
		}
		return null;

	}

	/**
	 * 插入操作
	 */
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		if (uriMatcher.match(uri) != USERSCODE) {
			throw new IllegalArgumentException("unknow URI" + uri);
		}
		SQLiteDatabase db = dh.getReadableDatabase();
		long rowId = db.insert("users", "username", values);
		// 监听数据变化,通知注册在uri上的监听者
		// 参数1:注册的uri,参数2:监听者
		getContext().getContentResolver().notifyChange(uri, null);
		return ContentUris.withAppendedId(uri, rowId);
	}

	/**
	 * 更新操作
	 */
	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = dh.getWritableDatabase();
		int rows = -1;
		switch ((uriMatcher.match(uri))) {
		case USERCODE:// 一个条目
			long id = ContentUris.parseId(uri);
			rows = db.update("users", values, "userid=?", new String[] { id
					+ "" });

			db.close();
			break;
		case USERSCODE:
			rows = db.update("users", values, selection, selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("unknow URI" + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rows;
	}

	/**
	 * 删除操作
	 */
	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = dh.getWritableDatabase();
		int rows = -1;
		switch ((uriMatcher.match(uri))) {
		case USERCODE:// 一个条目
			long id = ContentUris.parseId(uri);
			rows = db.delete("users", "userid=?", new String[] { id + "" });
			db.close();
			break;
		case USERSCODE:
			rows = db.delete("users", selection, selectionArgs);
			break;
		default:
			throw new IllegalArgumentException("unknow URI" + uri);
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return rows;
	}
}


android_providers项目布局文件

activity_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"
    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=".MainActivity" >

    <TextView
        android:id="@+id/tv_tip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="15dp"
        android:gravity="center"
        android:textColor="#FF0000"
        android:visibility="gone" />

    <ListView
        android:id="@+id/lv_users"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/ll_title"
        android:layout_marginTop="5dp" >
    </ListView>

    <LinearLayout
        android:id="@+id/ll_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_tip"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="100dp"
            android:layout_height="wrap_content"
            android:text="姓名" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="电话" />
    </LinearLayout>

</RelativeLayout>


item_phone.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp" />

    <TextView
        android:id="@+id/tv_phone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
           android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp" />

</LinearLayout>


android_providers项目MainActivity

package com.example.android_providers;

import android.app.Activity;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity implements OnScrollListener {
	private ListView lv_users;
	private TextView tv_tip;
	private SimpleCursorAdapter adapter;
	private ContentResolver contentResolver;
	private static final String URL = "content://www.csdn.com.provider.userContentProvider/users";
	public static final int INSERT = 1;
	private boolean flag = false;
	private boolean isLastRow = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		lv_users = (ListView) findViewById(R.id.lv_users);
		tv_tip = (TextView) findViewById(R.id.tv_tip);
		// 获取内容解析器对象
		contentResolver = getContentResolver();
		initDate();

		// 注册监听器
		getContentResolver().registerContentObserver(Uri.parse(URL), true,
				new UserContentObserver(handler));

		lv_users.setOnScrollListener(this);
	}

	/*
	 * 初始化数据
	 */
	private void initDate() {
		// 执行查询
		Cursor c = contentResolver.query(Uri.parse(URL), new String[] {
				"userid as _id", "username", "userphone" }, null, null,
				"userid desc");
		// 控制层
		adapter = new SimpleCursorAdapter(this, R.layout.item_phone, c,
				new String[] { "username", "userphone" }, new int[] {
						R.id.tv_name, R.id.tv_phone },
				SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

		lv_users.setAdapter(adapter);
	}

	class UserContentObserver extends ContentObserver {

		private Handler handler;

		public UserContentObserver(Handler handler) {
			super(handler);
			this.handler = handler;
		}

		@Override
		public void onChange(boolean selfChange) {
			super.onChange(selfChange);
			// 发送空消息
			handler.sendEmptyMessage(INSERT);
		}

	}

	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			switch (msg.what) {
			case INSERT:
				tv_tip.setVisibility(View.VISIBLE);
				flag = true;
				tv_tip.setText("有新的信息,请下拉加载......");
				break;

			default:
				break;
			}
		}

	};

	/**
	 * view firstVisibleItem 第一个显示的条目的位置(下标从0开始) visibleItemContent
	 * 可见的条目数(包含没有显示全的) totalVisibleItem 总条数(下标从0开始)
	 */
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemContent, int totalVisibleItem) {
		if ((firstVisibleItem + visibleItemContent) >= totalVisibleItem
				&& totalVisibleItem > 0) {
			// 发送请求处理
			isLastRow = true;
		}
	}

	// 正在滚动时回调,回调2-3次,手指没抛则回调2次。scrollState = 2的这次不回调
	// 回调顺序如下
	// 第1次:scrollState = SCROLL_STATE_TOUCH_SCROLL(1) 正在滚动当屏幕滚动且用户使用的触碰或手指还在屏幕上
	// 第2次:scrollState = SCROLL_STATE_FLING(2) 手指做了抛的动作(手指离开屏幕前,用力滑了一下)
	// 第3次:scrollState = SCROLL_STATE_IDLE(0) 停止滚动
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// (有新消息)更新的时候加载数据
		if (flag && scrollState == OnScrollListener.SCROLL_STATE_FLING) {
			// 初始化数据
			initDate();
			flag = false;
			tv_tip.setVisibility(View.GONE);

		}
		if (isLastRow && scrollState == OnScrollListener.SCROLL_STATE_FLING) {
			// 数据处理

		}
	}
}


转载请标明地址

/article/1344647.html
标签: