1.数据表必须有个字段是"_id",设置为主键并且自增长
integer primary key autoincrement
2.CursorAdapter+直接sqlite:
定义CursorAdapter:
newview方法在插入新数据的时候调用
bindview在显示任何一个item时调用(插入新数据先newview,在bind,重绘老数据直接bind)
public class MyCursorAdapter extends CursorAdapter { Context context = null; public MyCursorAdapter(Context context, Cursor c, boolean autoRequery) { super(context, c, autoRequery); } public MyCursorAdapter(Context context, Cursor c) { super(context, c); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { ViewHolder viewHolder = new ViewHolder(); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.item_contacts, parent, false); viewHolder.tv_name = (TextView) view.findViewById(R.id.tv_showusername); viewHolder.tv_phonenumber = (TextView) view.findViewById(R.id.tv_showusernumber); view.setTag(viewHolder); Log.i("cursor", "newView=" + view); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { Log.i("cursor", "bindView=" + view); ViewHolder viewHolder = (ViewHolder) view.getTag(); String name = cursor.getString(cursor.getColumnIndex(PersonInfo.NAME));//从数据库中查询姓名字段 String phoneNumber = cursor.getString(cursor.getColumnIndex(PersonInfo.PHONENUMBER));//从数据库中查询电话字段 viewHolder.tv_name.setText(name); viewHolder.tv_phonenumber.setText(phoneNumber); } @Override public void changeCursor(Cursor cursor) { super.changeCursor(cursor); } class ViewHolder { TextView tv_name; TextView tv_phonenumber; } }
初始化listview,设置adapter为MyCursorAdapter,构造函数传入初始查询到数据对应的cursor
private void initData() { openHelper=new InfoDatabaseHelper(this); dataBase=openHelper.getWritableDatabase(); orderBy="_id desc"; Cursor myCursor = dataBase.query(PersonInfo.PERSON_INFO_TABLE,null,null,null,null,null,orderBy); myCursorAdapter=new MyCursorAdapter(MainActivity.this,myCursor); lv_test.setAdapter(myCursorAdapter); }
数据改变时,重新查询数据,获得新的cursor,调用changecursor通知listview更新数据(相当于notifydatasetchange)
ContentValues contentValues=new ContentValues(); contentValues.put(PersonInfo.NAME,userName); contentValues.put(PersonInfo.PHONENUMBER,userPhoneNumber); //把EditText中的文本插入数据库 dataBase.insert(PersonInfo.PERSON_INFO_TABLE,null,contentValues); //根据 _id 降序插叙数据库保证最后插入的在最上面 Cursor myCursor = dataBase.query(PersonInfo.PERSON_INFO_TABLE,null,null,null,null,null,orderBy); //Cursor改变调用chanageCursor()方法 myCursorAdapter.changeCursor(myCursor);
3.CursorAdapter+ContentProvider:
contentprovider可以可以注册观察者,当数据改变时,通知观察着更新数据,在观察者里面,调用changecursor,省去了重新查询这一步
创建adapter时,先不查询数据,cursor指定为null
mCursorAdapter = new MyCursorAdapter(this, null, false); if(mPersonList != null) { mPersonList.setAdapter(mCursorAdapter); }
在activity的onCreate中注册观察者(这里是activity本身)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); getLoaderManager().initLoader(0, null, this); // id, args, loadercallbacks }
public class MainActivity extends Activity implements OnClickListener, LoaderCallbacks<Cursor>
观察者3个回调:
创建Loader:只调用一次,返回CursorLoader,传入contentprovider的uri
每次contentprovider数据改变,通知观察者时,会回调LoadFinished,这里调用changeCursor通知adapter数据改变
@Override public Loader<Cursor> onCreateLoader(int id, Bundle bundle) { return new CursorLoader(getApplicationContext(), Constants.PersonCursor.CONTENT_URI, null, null, null, null); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mCursorAdapter.changeCursor(data); } @Override public void onLoaderReset(Loader<Cursor> loader) { mCursorAdapter.changeCursor(null); }
contentprovider数据改变时,通知它的观察者:
@Override public Uri insert(Uri uri, ContentValues values) { Log.d(TAG, "insert(Uri=" + uri + ", values=" + values+");"); // 获取数据库 SQLiteDatabase db = mSQLiteHelper.getWritableDatabase(); String nullColumnHack = null; long rowID = -1; if(uriMatcher.match(uri) == PersonCursor_ALL_ROWS) { rowID = db.insert(Constants.PersonCursor.TABLE_NAME, nullColumnHack, values); } if(rowID > -1) { // 获取新插入数据行的Uri 等同于 uri.parse(BASE_PATH +"/" + id) Uri returnId = ContentUris.withAppendedId(uri, rowID); // 通知观察者更新数据 getContext().getContentResolver().notifyChange(returnId, null); return returnId; } else { throw new SQLException("Problem while inserting into Uri:" + uri); } } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { Log.d(TAG, "delete(uri=" + uri +");"); SQLiteDatabase db = mSQLiteHelper.getWritableDatabase(); String rowId = ""; int deleteCount = 0; switch(uriMatcher.match(uri)) { case PersonCursor_ALL_ROWS: deleteCount = db.delete(Constants.PersonCursor.TABLE_NAME, selection, selectionArgs); break; case PersonCursor_SINGLE_ROWS: rowId = uri.getPathSegments().get(1); selection = Constants.PersonCursor.KeyColumns.KEY_ID + " = " + rowId + (!TextUtils.isEmpty(selection) ? " AND (" + selection +")" : ""); deleteCount = db.delete(Constants.PersonCursor.TABLE_NAME, selection, selectionArgs); break; } if(deleteCount > 0) { // 通知观察者更新数据 getContext().getContentResolver().notifyChange(uri, null); } return deleteCount; }
3.SimpleCursorAdapter,cursoradapter的简单实现,用法类似于simpleadapter:
orderBy = "_id desc"; Cursor myCursor = dataBase.query(PersonInfo.PERSON_INFO_TABLE, null, null, null, null, null, orderBy); simpleCursorAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, myCursor, new String[]{PersonInfo.NAME, PersonInfo.PHONENUMBER}, new int[]{android.R.id.text1, android.R.id.text2}); lv_test.setAdapter(simpleCursorAdapter);
ContentValues contentValues = new ContentValues(); contentValues.put(PersonInfo.NAME, userName); contentValues.put(PersonInfo.PHONENUMBER, userPhoneNumber); //把EditText中的文本插入数据库 dataBase.insert(PersonInfo.PERSON_INFO_TABLE, null, contentValues); //根据 _id 降序插叙数据库保证最后插入的在最上面 Cursor myCursor = dataBase.query(PersonInfo.PERSON_INFO_TABLE, null, null, null, null, null, orderBy); //Cursor改变调用chanageCursor()方法 simpleCursorAdapter.changeCursor(myCursor);