之前两篇文章分别介绍了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条数据
- 删除操作
- 监听数据变化
- 获取控件对象
- listView
- tv_tip,tv_name,tv_phone
- 获取内容解析器对象
- 初始化数据
- 通过内容解析器对象执行查询
- 设置adapter
- 注册监听器
- 新建class继承ContentObserver类
- 绑定handler对象
- 根据请求处理数据
- 重写onChange(booleab selfChange)方法发送handler的message消息
- 绑定handler对象
- 新建class继承ContentObserver类
- 实现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) { // 数据处理 } } }
转载请标明地址
赵雅智_android实例_当监听类有数据更新时下拉刷新,布布扣,bubuko.com
时间: 2024-12-26 06:08:29