实现类似电话本显示的功能,情景如下:
一部新手机电话本为空,打开电话本,空显示,此时用91助手从PC导入电话号码,此时电话本的UI同步显示出来。
实现如上方法,要用到2个方面的知识,cursorAdapter和Observer
package listview;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.os.Handler;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.studymar.radiocheckbox.R;
public class MyCursorAdapter extends CursorAdapter {
Context ccContext=null;
Cursor cursor=null;
MyContentObserver mcoContentObserver=null;
public MyCursorAdapter(Context context, Cursor c) {
super(context, c);
this.ccContext=context;
this.cursor=c;
mcoContentObserver=new MyContentObserver();
//为cursor注册一个观察者
//database table中有变动后通知用户刷新cursor中的数据,但是在provider的query中必须调用cursor.setNotificationUri(context, uri);
//在insert和update中添加getContext().getContentResolver().notifyChange(uri, null)方法
c.registerContentObserver(mcoContentObserver);
//cursor中的数据有变动时调用到此onchange中通知用户刷新界面。
c.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
// TODO Auto-generated method stub
super.onChanged();
Log.i("123", "temp datasetobserver");
//此方法会通知cursoradapter来调用getView刷新界面
notifyDataSetChanged();
}
});
}
@Override
public void bindView(View arg0, Context arg1, Cursor arg2) {
TextView t1=null;
TextView t2=null;
t1=(TextView)arg0.findViewById(R.id.stname);
t2=(TextView)arg0.findViewById(R.id.stid);
t1.setText(arg2.getInt(0)+"");
t2.setText(arg2.getString(1));
}
@Override
public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
View view =null;
LayoutInflater vi = null;
vi = (LayoutInflater)ccContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view =vi.inflate(R.layout.cursorlistxml, arg2, false);
return view;
}
public class MyContentObserver extends ContentObserver {
public MyContentObserver(){
super(new Handler());
Log.i("123", "MyContentObserver method");
}
@Override
public void onChange(boolean selfChange) {
// TODO Auto-generated method stub
super.onChange(selfChange);
Log.i("123", "MyContentObserver onChange!");
//调用数据更新,这个数据更新的函数可以是acitvity中的某个函数,也可以是后台线程的某个函数
refreshData();
}
}
private void refreshData() {
//调用此方法会走到数据观察者的onChange()方法中
cursor.requery();
}
}
测试代码如下:
insertButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ContentValues contentValues=new ContentValues();
contentValues.put("_id", 3);
contentValues.put("name", "wangwu");
getContentResolver().insert(Uri.parse("content://com.stamars.sqlite.sqlite/student"), contentValues);
}
});
Uri queryUri=Uri.parse("content://com.stamars.sqlite.sqlite/student");
c=this.getContentResolver().query(queryUri, new String[]{"_id","name"}, null,null, null);
Log.i("123", "TestListView c="+c);
MyCursorAdapter cursorAdapter=new MyCursorAdapter(this, c);
myListView.setAdapter(cursorAdapter);