`

Android(OPhone) 学习笔记 - 记事本实例

阅读更多

系统自带的记事本实例。通过该例子,我们可以学会如何去阅读、分析、学习、模仿、思考他人写的代码。

一、工程结构

该工程位于SDK自带的Android的exmaple中。

    与我们之前看到的不同的是,该工程有多个java文件,不要担心,这是为了使程序的结构清晰,大多文件中代码只有几行而已。

1.AndroidManifest.xml

前面罗嗦而又有必要地说了它用的是Apache License 2.0,接下来可以清晰地看到,该程序有一个provider和三个activity。

provider中,这里声明了一个NotePadProvider。

<provider android:name="NotePadProvider" android:authorities="com.google.provider.NotePad"
/>

在代码中找到NotePadProvider.java这个文件,它用来管理数据库的存取以及应用程序间的共享。

再来看activity中的NotesList,在intent这块:

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
</intent-filter>

这里有三个filter,第一个大家都在前面的程序中见过,指明了这个activity是作为入口activity,系统查找到它后,就会创建这个activity实例来运行。第二个我们猜测它设计了查看、编辑等操作,第三个我们猜测它设计了获取内容的操作。其他的几个activity类似。

 

2.layout

在res/layout中有三个文件,我们可以理解成具有三个界面。

noteslist_item是记事本的notes列表界面,note_editor是编辑界面,title_editor是标题编辑界面,由文本输入框和按钮构成。

 

二、代码

1.NotesList.java

在该文件的变量定义处,有:

因为该记事本的记录是用数据库形式存储的,数据库有两个字段,一个是ID一个是TITLE。

进入onCreate之后,新建一个intent:

该Notes.CONTENT_URI可以通过按住shift键点击鼠标查到:

public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");

再次跟踪AUTHORITY,得到:

public static final String AUTHORITY = "com.google.provider.NotePad";

所以setData的参数就是:"content:// com.google.provider.NotePad/notes"。该notes就是数据表,保存所有的记事本条目和内容。

 

完成intent设定后,新建cursor对象,这个cursor可不是我们的鼠标指针,而是在数据库中的指针,可以参加前面的数据库文章,

Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null,Notes.DEFAULT_SORT_ORDER);

第一个参数就是上面设置的"content:// com.google.provider.NotePad/notes"这个URI,即notes数据表。PROJECTION 字段指明了结果中所需要的字段,Notes.DEFAULT_SORT_ORDER 指明了结果的排序规则。实际上managedQuery并没有直接去查询数据库,而是通过Content Provider来完成实际的数据库操作,这样就实现了逻辑层和数据库层的分离。

在create的最后,有如下代码:


SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
new String[] { Notes.TITLE }, new int[] { android.R.id.text1 });
setListAdapter(adapter);

该段代码将数据库和view进行映射。将鼠标移到SimpleCursorAdapter处,显示说明:

An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file. You can specify which columns you want, which views you want to display the columns, and the XML file that defines the appearance of these views. Binding occurs in two phases.

context   上下文环境,在此指本activity的环境

layout   view所在的layout

c   需要映射到数据库指针

from   绑定至界面的映射源数据。

to   视图显示的view,这里是android.R.id.text1,在noteslist_item.xml中可以看到它的TextView的android:id="@android:id/text1"。

create结束后,是菜单的操作。android提供了三种菜单类型,分别为options menu,context menu,sub menu。options menu就是通过按home键来显示,context menu需要在view上按上2s后显示。这两种menu都有可以加入子菜单,子菜单不能种不能嵌套子菜单。options menu最多只能在屏幕最下面显示6个菜单选项,称为icon menu,icon menu不能有checkable选项。多于6的菜单项会以more icon menu来调出,称为expanded menu。options menu通过activity的onCreateOptionsMenu来生成,这个函数只会在menu第一次生成时调用。任何想改变options menu的想法只能在onPrepareOptionsMenu来实现,这个函数会在menu显示前调用。onOptionsItemSelected 用来处理选中的菜单项。

在创建optionmenu时,有下列代码:

前面的menu.add,实现如下效果:

后面的这段代码的解释比代码还长,让我们来看看说了什么。这个类似插件,允许其他应用程序用它们的action扩展它们自己的activity的menu。若某一个activity,其类型是 "android.intent.category.ALTERNATIVE",数据是"vnd.android.cursor.dir/vnd.google.note"的话,系统就会为这个activity增加一个菜单项。

在手机信息管理的软件的AndroidManifest.xml中添加,并在onPrepareOptionsMenu中注释掉一段覆盖菜单的代码:

// ... is followed by whatever other actions are available...
Intent intent = new Intent(null, uri);
intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,
items);

就可以在此菜单中添加对其他行为的调用。如下所示:

点击菜单可以开启tele程序,即可获得手机信息。

 

最后是点击记事本的列表的响应。

protected void onListItemClick(ListView l, View v, int position, long id) {
  Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
String action = getIntent().getAction();
  if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {   
setResult(RESULT_OK, new Intent().setData(uri));
  } else {
startActivity(new Intent(Intent.ACTION_EDIT, uri));
}
}

通过”content:// com.google.provider.NotePad/notes”和日志的id 号拼接得到选中日志的真正URI,然后创建一个新的Intent,其操作类型为Intent.ACTION_EDIT,数据域指出待编辑的日志URI。通过startactivity来启动一个新的intent,进行记事本编辑。

同样在菜单中,也有类似的行为来实现新的activity:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics