android新闻app实现下拉刷新,Android实例_当监听类有数据更新时下拉刷新

之前两篇文章分别介绍了OnScrollListener的实现和ContentProvider监听数据的变化,下面我们就结合者两个知识点实现一个小项目

项目需求

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

实现效果

通过ContentProvider显示数据在界面

c2111b7c417e6e8d52efecbbd8d593fd.png

当监听类发生变化时

4af5865c6258928e72cee6d5b00d0123.png

下拉刷新后显示数据

f9f826522bcc704970ca9602233f8dfa.png

实现步骤

android_sqlite项目 定义操作标识匹配结果码继承ContentProvider类重写方法 oncreate初始化数据DatabaseHelpergetType

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

insert 匹配uri插入操作监听数据变化 update 匹配多条数据还是1条数据更新操作监听数据变化 query 匹配多条数据还是1条数据查询操作 delete 匹配多条数据还是1条数据删除操作监听数据变化 android_providers项目 获取控件对象 listViewtv_tip,tv_name,tv_phone 获取内容解析器对象初始化数据 通过内容解析器对象执行查询设置adapter 注册监听器 新建class继承ContentObserver类 绑定handler对象 根据请求处理数据 重写onChange(booleab selfChange)方法发送handler的message消息 实现OnScrollListener接口并实现方法 onScrollonScrollStateChanged 初始化数据隐藏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

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" >

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" />

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" >

android:id="@+id/ll_title"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_below="@+id/tv_tip"

android:orientation="horizontal" >

android:layout_width="100dp"

android:layout_height="wrap_content"

android:text="姓名" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="电话" />

item_phone.xml

android:id="@+id/ll_title"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:orientation="horizontal" >

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" />

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" />

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) {

// 数据处理

}

}

}

地址

http://blog.csdn.net/zhaoyazhi2129/article/details/30064965

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值