ListView,CursorAdapter,ContextMenu之间的映射关系学习笔记。
来源:互联网 发布:沙特知乎 编辑:程序博客网 时间:2024/06/06 02:52
这几天在学习NotePad的源码,对其中的ListView,CursorAdapter,ContextMenu数据之间的映射关系仔细研究了一下,在这记录一下。
在这先说一下SQLiteDatabase中的insert()这个方法的返回值为插入数据行的ID,具体在ContentProvider中的insert()方法中有引用:
@Overridepublic Uri insert(Uri uri, ContentValues initValues) {// TODO Auto-generated method stubif (uriMatcher.match(uri) != NOTES) {throw new IllegalArgumentException("Invalid uri" + uri);}ContentValues values;if (initValues != null) {values = new ContentValues(initValues);} else {values = new ContentValues();}long now = Long.valueOf(System.currentTimeMillis());if (values.containsKey(Notes.CREATED_DATE) == false) {values.put(Notes.CREATED_DATE, now);}if (values.containsKey(Notes.MODIFIED_DATE) == false) {values.put(Notes.MODIFIED_DATE, now);}if (values.containsKey(Notes.NOTE) == false) {values.put(Notes.NOTE, "");}if (values.containsKey(Notes.TITLE) == false) {values.put(Notes.TITLE,getContext().getResources().getString(R.string.untitle));}SQLiteDatabase db = myDBHelper.getWritableDatabase();long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);Log.e(TAG, "from insert=>rowId:" + rowId);if (rowId > 0) {Uri noteUri = ContentUris.withAppendedId(Notes.CONTENT_URI, rowId);getContext().getContentResolver().notifyChange(noteUri, null);// 这个noteUri改成uri行吗,就是不带Id的那种,写完和实验一下return noteUri;}throw new SQLiteException("Insert Note Fail! uri=>" + uri);}有上面的代码可以看到,在插入值的时候并没有指定Notes._ID的值,但是当你插入的时候会自动分配一个ID给属性Notes._ID列,默认的情况下,这个ID是自增的。
也就是会比当前最大的那个id+1(可能由于删除操作,删除前面的行,比如说一共有18行,1~18,删掉第一行,还剩2~18,再插入一行数据之后,数据的ID列在数据库中的
值是19);首先对这个ID的来源有所了解了,你会发现以后在查询的时候凡是用到映射的地方都会在映射中加入ID,因为在ListView中显示的Item的ID就是在数据库中ID列
的值,而不是在SimpleCursorAdapter的位置,SimpleCursorAdapter的位置对应的是ListView的从头到尾显示的顺序,现在说好像有点抽象,上图。
每个Item都会有一个ID,该ID对应的值也就是在数据库中Notes._ID对应的值,知道这个Notes._ID和ListView之间的关系了吧,
也就是ListView中的Item的ID对应的就是每行数据的ID列的值,这也就是为什么一般使用ContentProvider的时候都会用到ID这一列
的原因,因为这样设计才能根据你的点击映射到数据库的数据上面。
那么Item的显示顺序是由什么来决定的呢?
答案是有CusorAdapter中的位置决定。由于CursorAdapter是对Cursor的适配,而Cursor又是根据一定条件按照一定顺序从数据库中
筛选出来的,所以Cursor中数据的顺序也就是显示的顺序。这跟数据行的ID没有什么关系。上图:
在NotePad中使用的是根据modified这一列的降序排列,也就是根据修改时间排列的,谁最后修改的排在最前面,但是可能这个data0的ID由于是在insert创建决定的,(
比如是在data1,data2之后,那么他的ID = 3而在CursorAdapter中的position是2(起始点是0,1,2))。
好了说了这么多好像把基本的脉络差不多里清楚了,那么再来研究一下这个ContextMenu();所谓的ContextMenu简单来说就是你长按一个VIew之后弹出来的菜单,
不过前提是你要给这个组件注册一下listener,View.setOnCreateContextMenuListener(Listener);对应在Notepad中的代码是:
getListView().setOnCreateContextMenuListener(this);
当完成注册之后呢,如果每次长按ListView中的一个Item就会触发onCreateContextMenu()这个回调函数,Notepad中的代码:
@Overridepublic void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo info) {AdapterContextMenuInfo menuinfo;try {menuinfo = (AdapterContextMenuInfo) info;} catch (ClassCastException e) {Log.e(TAG, "from onCreateContextMenu()");return;}Cursor cursor = (Cursor) getListAdapter().getItem(menuinfo.position);if (cursor == null) {Log.e(TAG, "cursor == null");return;}menu.setHeaderTitle(cursor.getString(TITLE_COLUME_INDEX));menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete);}
关键是这几个参数的理解,上官方文档~
Called when the context menu for this view is being built. It is not safe to hold onto the menu after this method returns.Parameters<span style="color:#CC0000;">menu </span>The context menu that is being built<span style="color:#CC0000;">v</span> The view for which the context menu is being built<span style="color:#CC0000;">menuInfo</span> Extra information about the item for which the context menu should be shown. This information will vary depending on the class of v.
menu也就是即将要创建的这个ContextMenu了;
v也就是你setOnCreateContextMenuListener()的View;
menuInfo就好呢有讲究了,详细说一下啊。
menuInfo的类型是ContextMenuInfo该类中有三个变量,上官方文档~
<span style="color:#CC0000;">public long id</span>Added in API level 1The row id of the item for which the context menu is being displayed.<span style="color:#CC0000;"> public int position</span>Added in API level 1The position in the adapter for which the context menu is being displayed.<span style="color:#CC0000;"> public View targetView</span>Added in API level 1The child view for which the context menu is being displayed. This will be one of the children of this AdapterView.id也就是Item的ID也就是数据行的ID;
position也就是在CursorAdapter中的位置,也就是Item的显示顺序对应的位置;
targetView也不知道干啥的。我getId一直都是-1,看官方文档的意思就是AdapterView的child,所谓的AdapterView就是该View的Child是由Adapter来决定的,常见的
就是ListView,GridView,Spinner和Gallery;
上面在onCreateContextMenu()中用到了menuinfo.position也就是CursorAdapter中的位置,通过Adapter.getItem(menuinfo.position)或的该行的数据行保留在Cursor
中,然后在通过Cursor获取每列的值。
好像寒不够充分,在说一下,点击弹出来的ContextMenu的Item的处理函数,onContextItemSelected():
@Overridepublic boolean onContextItemSelected(MenuItem item) {AdapterContextMenuInfo menuinfo;try {menuinfo = (AdapterContextMenuInfo) item.getMenuInfo();} catch (ClassCastException e) {Log.e(TAG, "from onContextItemSelected()");return false;}switch (item.getItemId()) {case MENU_ITEM_DELETE:Uri uri = ContentUris.withAppendedId(getIntent().getData(),menuinfo.id);getContentResolver().delete(uri, null, null);return true;}return false;}
这个函数中通过MenuInfo的id获得数据的Id,然后根据id删除相应的数据行。
说到这,相信也基本把ListView,SimpleCursorAdapter,ContextMenu三者的映射关系
- ListView,CursorAdapter,ContextMenu之间的映射关系学习笔记。
- ContentProvider,Cursor,CursorAdapter之间的关系图。
- Cursor,CursorAdapter学习笔记
- Hibernate笔记2--映射对象之间的关系
- Hibernate的学习总结(映射类之间的组合关系)
- Hibernate的学习总结(映射类之间的继承关系)
- Android学习笔记(四二):SQLite、ListView、ContextMenu
- Android学习笔记(四二):SQLite、ListView、ContextMenu
- Android学习笔记(四二):SQLite、ListView、ContextMenu .
- listview上的CursorAdapter使用
- 【Java学习笔记】类之间的关系
- Android ListView上的ContextMenu
- JPA学习笔记-映射单向一对多的关联关系
- JPA学习笔记-映射双向一对多的关联关系
- JPA学习笔记-映射双向一对一的关联关系
- hibernate3.3.2学习笔记---映射继承的关系
- ListView结合CursorAdapter自动更新view的流程
- ListView+CursorAdapter+LoaderManger的配合使用
- hdu2544最短路
- 额特然图一5有人有人特与人同意
- XML中DTD,XSD的区别与应用
- POJ 3282 Ferry Loading IV(简单模拟)
- 单例模式的七种写法
- ListView,CursorAdapter,ContextMenu之间的映射关系学习笔记。
- Java基础知识之Class结构
- poj3159(差分约束)
- Orz教主第五次模拟(做题情况+题目分析+代码)[未完]
- springMVC源码下载
- UVa 11538 - Chess Queen (组合数学)
- editplus创建时候的几个注意事项
- 线段树模板
- day01