首页 > 代码库 > 赵雅智_android实例_当监听类有数据更新时下拉刷新

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

之前两篇文章分别介绍了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 = http://www.mamicode.com/null;>

    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) {
    			// 数据处理
    
    		}
    	}
    }
    


    转载请标明地址

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