教程:Notepad练习2
In this exercise, you will add a second Activity to your notepad application, to let the user create, edit, and delete notes. The new Activity assumes responsibility for creating new notes by collecting user input and packing it into a return Bundle provided by the intent. This exercise demonstrates:
在这个练习之中,你会增加第二个活动进入你的notepad程序,让用户创建、编辑、删除便签。新的Activity呈现的职责是创建新的便签来收集用户输入、打包进入一个返回的由intent提供的Bundle,这个练习证明了:
* Constructing a new Activity and adding it to the Android manifest
1、构造新Activity,增加进入Android manifext
* Invoking another Activity asynchronously using startActivityForResult()
2、使用startActivityForResult()异步调用另外一个Activity
* Passing data between Activity in Bundle objects
3、在Activity间使用Bundle对象传递数据
* How to use a more advanced screen layout
4、怎么使用更多的高级界面布局
Step 1
第一步
Create a new Android project using the sources from Notepadv2 under the NotepadCodeLab folder, just like you did for the first exercise. If you see an error about AndroidManifest.xml, or some problems related to an android.zip file, right click on the project and select Android Tools > Fix Project Properties.
创建新Android项目,使用NotepadCodeLab文件夹的Notepadv2源代码,和练习1的做法相同。如果你看到AndroidManifest.xml的错误,或者android.zip的问题,在project上右击,选择Android Tools > Fix Project Properties
Open the Notepadv2 project and take a look around:
打开Notepadv2项目,全部看一看:
* Open and look at the strings.xml file under res/values — there are several new strings which we will use for our new functionality
1、打开strings.xml 并查看——新功能会用到几个新的字符串
* Also, open and take a look at the top of the Notepadv2 class, you will notice several new constants have been defined along with a new mNotesCursor field used to hold the cursor we are using.
2、打开 Notepadv2类,看看顶部的代码,你会注意到定义了几个新常量,和新的mNotesCursor属性一起用于存储我们正在使用的游标。
* Note also that the fillData() method has a few more comments and now uses the new field to store the notes Cursor. The onCreate() method is unchanged from the first exercise. Also notice that the member field used to store the notes Cursor is now called mNotesCursor. The m denotes a member field and is part of the Android coding style standards.
3、fillData()方法有更多的注释,使用新的字段来保存便签游标。onCreate()方法没有改变。用于保存便签游标的成员变量现在称为mNotesCursor。m指示一个成员属性,是Android代码风格标准的一部分。
* There are also a couple of new overridden methods (onListItemClick() and onActivityResult()) which we will be filling in below.
4、还有一对新的重载方法:onListItemClick() 和onActivityResult(),下面我们会填充它们。
Step 2
第二步
Add an entry to the menu for deleting a note:
增加删除便签的菜单入口:
1. In the onCreateOptionsMenu() method, add a new line:
1、在方法onCreateOptionsMenu()中增加新行:
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
2. The whole method should now look like this:
2、整个方法的代码如下:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, INSERT_ID, 0, R.string.menu_insert);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
return true;
}
Step 3
第三步
In the onMenuItemSelected() method, add a new case for DELETE_ID:
onMenuItemSelected()增加新代码,关联DELETE_ID:
mDbHelper.deleteNote(getListView().getSelectedItemId());
fillData();
return true;
1. Here, we use the deleteNote method to remove the note specified by ID. In order to get the ID, we call getListView().getSelectedItemId().
1、使用deleteNote方法,通过ID移除便签。为了获取ID,我们调用getListView().getSelectedItemId()
2. Then we fill the data to keep everything up to date.
2、我们填充数据以保证每件事情最新
The whole method should now look like this:
整个方法的代码:
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch(item.getItemId()) {
case INSERT_ID:
createNote();
return true;
case DELETE_ID:
mDbHelper.deleteNote(getListView().getSelectedItemId());
fillData();
return true;
}
return super.onMenuItemSelected(featureId, item);
}
Step 4
第四步
Starting Other Activities
启动其他的Activity
In this example our Intent uses a class name specifically. As well as starting intents in classes we already know about, be they in our own application or another application, we can also create Intents without knowing exactly which application will handle it.
这个例子中,Intent使用一个特定的类名。又在类中启动intent,正如我们知道的那样,是他们在我们自己的程序或者其他程序中,我们也能创建Intent而不知道哪个程序处理它。
For example, we might want to open a page in a browser, and for this we still use an Intent. But instead of specifying a class to handle it, we use a predefined Intent constant, and a content URI that describes what we want to do. See android.content.Intent for more information.
例如,我们可能想在浏览器中打开一个页面,为了这个目的,我们人就使用Intent。但不是指定一个类来处理它,我们使用一个预定义的Intent常量,一个内容URI(描述我们想做什么)。欲知更多信息,请看“android.content.Intent ”。
Fill in the body of the createNote() method:
填写createNode()方法的代码:
Create a new Intent to create a note (ACTIVITY_CREATE) using the NoteEdit class. Then fire the Intent using the startActivityForResult() method call:
创建新的Intent来创建一个便签(ACTIVITY_CREATE),使用NoteEdit类。然后,调用startActivityForResult(),触发Intent:
Intent i = new Intent(this, NoteEdit.class);
startActivityForResult(i, ACTIVITY_CREATE);
This form of the Intent call targets a specific class in our Activity, in this case NoteEdit. Since the Intent class will need to communicate with the Android operating system to route requests, we also have to provide a Context (this).
这种Intent调用的形式瞄准Activity中的特定类,这个例子中指NoteEdit。因为Intent类会需要与Android操作系统通讯,目的是路由请求消息,我们也不得不提供Context(this)。
The startActivityForResult() method fires the Intent in a way that causes a method in our Activity to be called when the new Activity is completed. The method in our Activity that receives the callback is called onActivityResult() and we will implement it in a later step. The other way to call an Activity is using startActivity() but this is a "fire-and-forget" way of calling it — in this manner, our Activity is not informed when the Activity is completed, and there is no way to return result information from the called Activity with startActivity().
startActivityForResult()方法触发Intent,这种方法促使Activity中的方法在新Activity完成时被调用。Activity中接受回调的方法是onActivityResult(),在稍后步骤中会实现它。调用Activity的其他方式是使用startActivity(),但是这种方法是"fire-and-forget"(发射后忘记)——使用这种方法,Activity完成时Activity消息并不灵通,startActivity()调用的Activity没有办法返回结果信息。
Don't worry about the fact that NoteEdit doesn't exist yet, we will fix that soon.
不要担心NoteEdit,我们会校正这个问题。
Step 5
第五步
Fill in the body of the onListItemClick() override.
填写onListItemClick()重载代码。
onListItemClick() is a callback method that we'll override. It is called when the user selects an item from the list. It is passed four parameters: the ListView object it was invoked from, the View inside the ListView that was clicked on, the position in the list that was clicked, and the mRowId of the item that was clicked. In this instance we can ignore the first two parameters (we only have one ListView it could be), and we ignore the mRowId as well. All we are interested in is the position that the user selected. We use this to get the data from the correct row, and bundle it up to send to the NoteEdit Activity.
onListItemClick()是一个回调函数,我们将会重载它。当用户从列表中选择一项时该函数自动被系统调用。四个参数:ListView对象、View(点击的ListView里面)、点击的列表位置、nRowId(点击的条目的记录ID)。这个例子中,我们忽略前面两个参数,也忽略mRowId。我们感兴趣的是用户选择的位置。我们使用这个方法获得正确行的数据,捆扎在一起送到NoteEdit活动。
In our implementation of the callback, the method creates an Intent to edit the note using the NoteEdit class. It then adds data into the extras Bundle of the Intent, which will be passed to the called Activity. We use it to pass in the title and body text, and the mRowId for the note we are editing. Finally, it will fire the Intent using the startActivityForResult() method call. Here's the code that belongs in onListItemClick():
在回调函数的实现中,创建Intent,以便使用NoteEdit类编辑便签。然后,增加数据进入Intent的附加Bundle中。新建的Intent对象传送给被调用的活动。我们使用它传入标题和内容文本,以及我们编辑的便签的mRowId。最后,使用startActivityForResult()方法发射Intent。下面的代码是onListItemClick()的实现:
super.onListItemClick(l, v, position, id);
Cursor c = mNotesCursor;
c.moveToPosition(position);
Intent i = new Intent(this, NoteEdit.class);
i.putExtra(NotesDbAdapter.KEY_ROWID, id);
i.putExtra(NotesDbAdapter.KEY_TITLE, c.getString(
c.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
i.putExtra(NotesDbAdapter.KEY_BODY, c.getString(
c.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
startActivityForResult(i, ACTIVITY_EDIT);
* putExtra() is the method to add items into the extras Bundle to pass in to intent invocations. Here, we are using the Bundle to pass in the title, body and mRowId of the note we want to edit.
1、putExtra()方法增加条目到附加的Bundle中,传入参数intent的引用。此处,我们使用Bundle来传入标题、内容、我们想编辑的便签的记录ID
* The details of the note are pulled out from our query Cursor, which we move to the proper position for the element that was selected in the list, with the moveToPosition() method.
2、从查询游标中读出便签的详细信息,游标的位置移动到列表中选中的元素的位置,使用moveToPosition()方法移动。
* With the extras added to the Intent, we invoke the Intent on the NoteEdit class by passing startActivityForResult() the Intent and the request code. (The request code will be returned to onActivityResult as the requestCode parameter.)
3、附加信息加入Intent中,我们在NoteEdit类型中调用Intent,吧Intent和请求代码传递给startActivityForResult()。(请求代码作为requestCode参数在onActivityResult中返回。)
Note: We assign the mNotesCursor field to a local variable at the start of the method. This is done as an optimization of the Android code. Accessing a local variable is much more efficient than accessing a field in the Dalvik VM, so by doing this we make only one access to the field, and five accesses to the local variable, making the routine much more efficient. It is recommended that you use this optimization when possible.
注意:我们把mNotesCursor属性赋值到本地变量,这是对Android代码的优化。访问本地变量比访问DalvikVM的一个属性更有效率,因此,这样做了后我们访问了这个属性一次,访问本地变量5次,使程序有效得多。推荐尽可能的使用这种优化方法。
Step 6
第六步
The above createNote() and onListItemClick() methods use an asynchronous Intent invocation. We need a handler for the callback, so here we fill in the body of the onActivityResult().
上面提到的createNote()和onListItemClick()方法使用了异步Intent引用。我们需要处理回调行数,因此,此处我们填充onActivityResult()代码。
onActivityResult() is the overridden method which will be called when an Activity returns with a result. (Remember, an Activity will only return a result if launched with startActivityForResult.) The parameters provided to the callback are:
onActivityResult()是一个重载方法,当Activity返回结果的时候被调用。(记住,如果使用startActivityForResult触发,则Activity仅仅会返回一个结果。) 回调函数提供的参数如下:
* requestCode — the original request code specified in the Intent invocation (either ACTIVITY_CREATE or ACTIVITY_EDIT for us).
1、requestCode——在Intent引用中指定的原始请求代码(要么是ACTIVITY_CREATE,要么是ACTIVITY_EDIT)
* resultCode — the result (or error code) of the call, this should be zero if everything was OK, but may have a non-zero code indicating that something failed. There are standard result codes available, and you can also create your own constants to indicate specific problems.
2、resultCode——调用的结果或者错误代码,如果一切都没有问题,应该是0,但是可以是非0值,则表示有错误发生。有标准的结果代码获得,你也可以创建你自己的常量来指示特定错误。
* intent — this is an Intent created by the Activity returning results. It can be used to return data in the Intent "extras."
3、intent——通过有返回结果的Activty创建的Intent。他能用于返回数据,数据存放在Intent的“extras”中。
The combination of startActivityForResult() and onActivityResult() can be thought of as an asynchronous RPC (remote procedure call) and forms the recommended way for an Activity to invoke another and share services.
startActivityForResult()和onActivityResult()的结合能作为异步RPC,提供活动相互调用和共享服务的推荐方法。
Here's the code that belongs in your onActivityResult():
下面是onActivityResult()的代码:
super.onActivityResult(requestCode, resultCode, intent);
Bundle extras = intent.getExtras();
switch(requestCode) {
case ACTIVITY_CREATE:
String title = extras.getString(NotesDbAdapter.KEY_TITLE);
String body = extras.getString(NotesDbAdapter.KEY_BODY);
mDbHelper.createNote(title, body);
fillData();
break;
case ACTIVITY_EDIT:
Long mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
if (mRowId != null) {
String editTitle = extras.getString(NotesDbAdapter.KEY_TITLE);
String editBody = extras.getString(NotesDbAdapter.KEY_BODY);
mDbHelper.updateNote(mRowId, editTitle, editBody);
}
fillData();
break;
}
* We are handling both the ACTIVITY_CREATE and ACTIVITY_EDIT activity results in this method.
1、在这个方法中,我们处理 ACTIVITY_CREATE 和 ACTIVITY_EDIT两种活动返回结果。
* In the case of a create, we pull the title and body from the extras (retrieved from the returned Intent) and use them to create a new note.
2、在创建的代码中,我们从extras获取标题和内容,然后用来创建新的便签。
* In the case of an edit, we pull the mRowId as well, and use that to update the note in the database.
3、在编辑的代码中,我们还是获取mRowId,然后用来修改数据库的便签数据。
* fillData() at the end ensures everything is up to date .
4、fillData()保证所有信息都是最新的。
Step 7
第七步
The Art of Layout
布局的艺术
The provided note_edit.xml layout file is the most sophisticated one in the application we will be building, but that doesn't mean it is even close to the kind of sophistication you will be likely to want in real Android applications.
note_edit.xml布局文件是我们建立的应用程序中最成熟的一个文件,但是那不并意味着接近你在真实Android程序中可能要求的那种成熟。
Creating a good UI is part art and part science, and the rest is work. Mastering Android layout is an essential part of creating a good looking Android application.
创建好的UI部分(参见“Android layout”)是艺术部分是科学,剩余的就是工作。掌握Android布局是创建好看的Android程序的基本部分。
Take a look at the View Gallery for some example layouts and how to use them. The ApiDemos sample project is also a great resource from which to learn how to create different layouts.
仔细看看一些例子的布局,研究怎么使用他们,参见“View Gallery”。ApiDemos例子项目也是好资源,可以学习了解怎么创建不懂的布局。
Open the file note_edit.xml that has been provided and take a look at it. This is the UI code for the Note Editor.
打开已经提供的note_edit.xml文件,仔细看看。这是Note Editor的UI代码。
This is the most sophisticated UI we have dealt with yet. The file is given to you to avoid problems that may sneak in when typing the code. (The XML is very strict about case sensitivity and structure, mistakes in these are the usual cause of problems with layout.)
这是我们已经处理的最成熟的UI。提供这个文件为了避免问题,这些问题可能由于键入代码而悄悄潜入。(XML是非常严格的,在大小写和结构等方面的错误是布局问题的最常见原因。)
There is a new parameter used here that we haven't seen before: android:layout_weight (in this case set to use the value 1 in each case).
这里有一个以前没有见过的新参数:android:layout_weight(本例中在所有情况下设置为值1)
layout_weight is used in LinearLayouts to assign "importance" to Views within the layout. All Views have a default layout_weight of zero, meaning they take up only as much room on the screen as they need to be displayed. Assigning a value higher than zero will split up the rest of the available space in the parent View, according to the value of each View's layout_weight and its ratio to the overall layout_weight specified in the current layout for this and other View elements.
layout_weight用在LinearLayouts中,在布局中赋值"importance"给View。所有View默认layout_weight值为0,意味着他们仅仅占据他们需要的显示空间。赋值大于0将会在父View中分割可获得的剩余空间,分割空间的依据是每个View的layout_weight的值,还有在View元素的现有布局中指定的全部layout_weight的比率。
To give an example: let's say we have a text label and two text edit elements in a horizontal row. The label has no layout_weight specified, so it takes up the minimum space required to render. If the layout_weight of each of the two text edit elements is set to 1, the remaining width in the parent layout will be split equally between them (because we claim they are equally important). If the first one has a layout_weight of 1 and the second has a layout_weight of 2, then one third of the remaining space will be given to the first, and two thirds to the second (because we claim the second one is more important).
举一个例子:假设我们在一行中有一个文本标签和两个文本编辑框。标签没有指定layout_weight,因此他占据必须的最小空间。如果两个文本编辑框的layout_weight都设置为1,可在父窗口中的剩余宽度被他们平分(因为我们声称他们同等重要)。如果第一个是1,第二个是2,那么剩余空间的三分之一分配给第一个,三分之二分配给第二个(因为我们要求第二个更重要)
This layout also demonstrates how to nest multiple layouts inside each other to achieve a more complex and pleasant layout. In this example, a horizontal linear layout is nested inside the vertical one to allow the title label and text field to be alongside each other, horizontally.
这个布局文件也证明怎么互相嵌套多个布局元素,以便获得更多复杂和合适的布局界面。本例中,水平线布局嵌套进入垂直线,以便允许标题标签和文本字段相互并排。
Step 8
第八步
Create a NoteEdit class that extends android.app.Activity.
创建NoteEdit类,继承android.app.Activity
This is the first time we will have created an Activity without the Android Eclipse plugin doing it for us. When you do so, the onCreate() method is not automatically overridden for you. It is hard to imagine an Activity that doesn't override the onCreate() method, so this should be the first thing you do.
我们第一次没有在ADT帮助下创建Activity。onCreate()方法没有自动重载。想像没有重载onCreate()方法的Activity是困难的,因此,首先要做的事情是重载onCreate()
1. Right click on the com.android.demo.notepad2 package in the Package Explorer, and select New > Class from the popup menu.
1、右击com.android.demo.notepad2包,从弹出菜单中选择 New > Class
2. Fill in NoteEdit for the Name: field in the dialog.
2、在对话框的“Name:”标签后填入“NoteEdit”
3. In the Superclass: field, enter android.app.Activity (you can also just type Activity and hit Ctrl-Space on Windows and Linux or Cmd-Space on the Mac, to invoke code assist and find the right package and class).
3、在“Superclass: ”标签中,键入“android.app.Activity”(你也能输入Activity,按 Ctrl-Space,启用代码助手找到正确的包和类)
4. Click Finish.
4、点击Finish
5. In the resulting NoteEdit class, right click in the editor window and select Source > Override/Implement Methods...
5、在NoteEdit类中,右击编辑窗口,选择菜单Source > Override/ImplementMethods...
6. Scroll down through the checklist in the dialog until you see onCreate(Bundle) — and check the box next to it.
6、滚动对话框中的清单,找到onCreate(Bundle)——选中前面的检查框
7. Click OK.
7、点击OK
The method should now appear in your class.
这个方法应该出现在你的类中。
Step 9
第九步
Fill in the body of the onCreate() method for NoteEdit.
填写onCreate()的代码
This will set the title of our new Activity to say "Edit Note" (one of the strings defined in strings.xml). It will also set the content view to use our note_edit.xml layout file. We can then grab handles to the title and body text edit views, and the confirm button, so that our class can use them to set and get the note title and body, and attach an event to the confirm button for when it is pressed by the user.
这里将会设置新活动的题目为“Edit Note”(在strings.xml文件中定义的一个字符串)。也会设置内容视图以便使用note_edit.xml布局文件。然后,处理标题和内容文本编辑框、确认按钮,因此,我们的类能使用他们来获取或者设置便签的标题和内容,附着事件到确认按钮,这个事件在用户按确认按钮时触发。
We can then unbundle the values that were passed in to the Activity with the extras Bundle attached to the calling Intent. We'll use them to pre-populate the title and body text edit views so that the user can edit them. Then we will grab and store the mRowId so we can keep track of what note the user is editing.
然后,我们对传入到Activity的值进行分类,传入值使用Activity的extras Bundle,extras Bundle附着到调用的Intent上。我们会使用他们来预先填充标题和内容文本编辑框,因此,用户能编辑他们。然后,我们会获取和存储mRowId,因此我们能留意用户编辑的什么便签。
1. Inside onCreate(), set up the layout:
1、在onCreate()内部,设置布局:
setContentView(R.layout.note_edit);
2. Find the edit and button components we need:
2、找到我们需要的编辑框和按钮组件:
These are found by the IDs associated to them in the R class, and need to be cast to the right type of View (EditText for the two text views, and Button for the confirm button):
在R类中,通过ID找到他们,需要强制转换到正确的视图类型(两个文本视图是EditText,确认按钮时Button)
mTitleText = (EditText) findViewById(R.id.title);
mBodyText = (EditText) findViewById(R.id.body);
Button confirmButton = (Button) findViewById(R.id.confirm);
Note that mTitleText and mBodyText are member fields (you need to declare them at the top of the class definition).
注意:mTitleText 和 mBodyText是成员变量(你需要在顶部声明他们)
3. At the top of the class, declare a Long mRowId private field to store the current mRowId being edited (if any).
3、在类的顶部,生命一个Long类型的mRowId私有变量,用来存储当前编辑的mRowId
4. Continuing inside onCreate(), add code to initialize the title, body and mRowId from the extras Bundle in the Intent (if it is present):
4、继续在onCreate()中增加代码来初始化标题、内容、mRowId,从Intent的extras Bundle(附加包)中获取初始化数据。
mRowId = null;
Bundle extras = getIntent().getExtras();
if (extras != null) {
String title = extras.getString(NotesDbAdapter.KEY_TITLE);
String body = extras.getString(NotesDbAdapter.KEY_BODY);
mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
if (title != null) {
mTitleText.setText(title);
}
if (body != null) {
mBodyText.setText(body);
}
}
* We are pulling the title and body out of the extras Bundle that was set from the Intent invocation.
(1)从来自Intent引用的extras Bundle中获取标题和内容
* We also null-protect the text field setting (i.e., we don't want to set the text fields to null accidentally).
(2)零保护文本框设置(例如,我们不想意外地设置文本框为null)
5. Create an onClickListener() for the button:
5、针对按钮创建onClickListener()
Listeners can be one of the more confusing aspects of UI implementation, but what we are trying to achieve in this case is simple. We want an onClick() method to be called when the user presses the confirm button, and use that to do some work and return the values of the edited note to the Intent caller. We do this using something called an anonymous inner class. This is a bit confusing to look at unless you have seen them before, but all you really need to take away from this is that you can refer to this code in the future to see how to create a listener and attach it to a button. (Listeners are a common idiom in Java development, particularly for user interfaces.) Here's the empty listener:
Listener使UI实现更混乱的一个方面,但是,本例中试图完成的事情是简单的。当用户按确认按钮时,调用onClieck()方法,用来完成一些工作并且然会被编辑的便签的值给Intent调用者。我们利用称为匿名内嵌类的东西来做这些事情。如果你以前没有见到过,那么看起来这有点混乱,但是,你实际需要取走(完成)的所有事情是可以在未来引用这里的代码,注意怎样创建一个Listener,并附着到一个按钮(Listener是Java开发的一个习惯用语,尤其是在UI方面)。下面是空的Listener:
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
}
});
Step 10
第十步
Fill in the body of the onClick() method in our listener.
填充侦听器里面的onClick()代码。
This is the code that will be run when the user clicks on the confirm button. We want this to grab the title and body text from the edit text fields, and put them into the return Bundle so that they can be passed back to the Activity that invoked this NoteEdit Activity. If the operation is an edit rather than a create, we also want to put the mRowId into the Bundle so that the Notepadv2 class can save the changes back to the correct note.
这些代码在用户点击确认按钮时运行。我们使用这些代码从编辑框中获取标题和内容文本串,然后把它们送给Bundle,以便他们能传回到Activity(NoteEdit Activity调用)。如果操作是编辑而不是创建,那么传送mRowId进入Bundle,以便Notepav2类能保存变化到正确的便签。
1. Create a Bundle and put the title and body text into it using the constants defined in Notepadv2 as keys:
1、创建Bundle,传递标题和内容文本到Bundle,使用在Notepadv2中定义的常量作为关键码:
Bundle bundle = new Bundle();
bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
if (mRowId != null) {
bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
}
2. Set the result information (the Bundle) in a new Intent and finish the Activity:
2、在新的Intent中设置结果信息(Bundle),完成Activity:
Intent mIntent = new Intent();
mIntent.putExtras(bundle);
setResult(RESULT_OK, mIntent);
finish();
* The Intent is simply our data carrier that carries our Bundle (with the title, body and mRowId).
(1)Intent是简单的数据运载工具,运载Bundle(携带标题、内容、mRowId)
* The setResult() method is used to set the result code and return Intent to be passed back to the Intent caller. In this case everything worked, so we return RESULT_OK for the result code.
(2)setResult()方法用于设置结果代码,返回Intent为了传回到Intent调用者。本例中,每件事情都正常工作,因此我们返回RESULT_OK作为结果代码
* The finish() call is used to signal that the Activity is done (like a return call). Anything set in the Result will then be returned to the caller, along with execution control.
(3)finish()调用用于发信号表明Activity被激发(像一个回调)。然后,在Result中设置的所有东西会返回给调用者,连同执行控制一起
The full onCreate() method (plus supporting class fields) should now look like this:
完整的onCreate()如下:
private EditText mTitleText;
private EditText mBodyText;
private Long mRowId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_edit);
mTitleText = (EditText) findViewById(R.id.title);
mBodyText = (EditText) findViewById(R.id.body);
Button confirmButton = (Button) findViewById(R.id.confirm);
mRowId = null;
Bundle extras = getIntent().getExtras();
if (extras != null) {
String title = extras.getString(NotesDbAdapter.KEY_TITLE);
String body = extras.getString(NotesDbAdapter.KEY_BODY);
mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
if (title != null) {
mTitleText.setText(title);
}
if (body != null) {
mBodyText.setText(body);
}
}
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Bundle bundle = new Bundle();
bundle.putString(NotesDbAdapter.KEY_TITLE, mTitleText.getText().toString());
bundle.putString(NotesDbAdapter.KEY_BODY, mBodyText.getText().toString());
if (mRowId != null) {
bundle.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
}
Intent mIntent = new Intent();
mIntent.putExtras(bundle);
setResult(RESULT_OK, mIntent);
finish();
}
});
}
Step 11
第11步
The All-Important Android Manifest File
非常重要的Android Manifest文件
The AndroidManifest.xml file is the way in which Android sees your application. This file defines the category of the application, where it shows up (or even if it shows up) in the launcher or settings, what activities, services, and content providers it defines, what intents it can receive, and more.
AndroidManifest.xml文件是Android领会你的程序的方式。这个文件定义了程序的类型,在发射器和设置里面露面的地方,定义了活动、服务、内容提供器是什么,能接收的intent是什么,等等。
For more information, see the reference document AndroidManifest.xml
欲知更多信息参见文档“AndroidManifest.xml”
Finally, the new Activity has to be defined in the manifest file:
最后,新Activity必须定义在manifest文件中:
Before the new Activity can be seen by Android, it needs its own Activity entry in the AndroidManifest.xml file. This is to let the system know that it is there and can be called. We could also specify which IntentFilters the activity implements here, but we are going to skip this for now and just let Android know that the Activity is defined.
在新Activity能被Android了解之前,需要在AndroidManifest.xml中定义自己的Activity入口。这是让系统知道它在那儿且能被调用。我们也能指定Activity实现哪个IntentFilters,但是我们打算暂时跳过这个,只是让Android知道Activity被定义了。
There is a Manifest editor included in the Eclipse plugin that makes it much easier to edit the AndroidManifest file, and we will use this. If you prefer to edit the file directly or are not using the Eclipse plugin, see the box at the end for information on how to do this without using the new Manifest editor.
在Eclipse插件中包含了一个Manifest编辑器,使AndroidManifest文件编辑更加容易,我们将会使用这个编辑器。
1. Double click on the AndroidManifest.xml file in the package explorer to open it.
1、在AndroidManifest.xml文件上双击打开它
2. Click the Application tab at the bottom of the Manifest editor.
2、在Manifest编辑器底部点击Application便签
3. Click Add... in the Application Nodes section.
3、在Application Nodes段中点击 Add...
If you see a dialog with radiobuttons at the top, select the top radio button: "Create a new element at the top level, in Application".
如果你在顶部看到一个带有单选按钮的对话框,那么选择顶部的单选按钮"Create a new element at the top level, in Application"
4. Make sure "(A) Activity" is selected in the selection pane of the dialog, and click OK.
4、保证 "(A) Activity"在对话框的选择面板中被选中,然后点击OK
5. Click on the new "Activity" node, in the Application Nodes section, then type .NoteEdit into the Name* field to the right. Press Return/Enter.
5、在 Application Nodes段中,点击新的"Activity"节点,然后在“Name*”标签右边输入.NoteEdit,按Return/Enter
The Android Manifest editor helps you add more complex entries into the AndroidManifest.xml file, have a look around at some of the other options available (but be careful not to select them otherwise they will be added to your Manifest). This editor should help you understand and alter the AndroidManifest.xml file as you move on to more advanced Android applications.
Android Manifest编辑器帮助你增加更多复杂的条目到AndroidManifest.xml文件中,仔细看看可获得的其他选项(但是小心不要选择他们否则他们会被加入到你的Manifest文件中)。这个编辑器应该帮助你理解和修改AndroidManifest.xml文件,当你移到更多高级的Android程序时会很有用处。
If you prefer to edit this file directly, simply open the AndroidManifest.xml file and look at the source (use the AndroidManifest.xml tab in the eclipse editor to see the source code directly). Then edit the file as follows:
如果你宁愿直接编辑这个文件,简单打开 AndroidManifest.xml文件,然后了解资源(使用eclipse编辑器的AndroidManifest.xml标签直接领悟源代码)。然后,按照下面这样编辑文件:
This should be placed just below the line that reads:
这应该表示:
for the .Notepadv2 activity.
针对.Notepadv2活动
Step 12
第12步
Now Run it!
现在运行。
You should now be able to add real notes from the menu, as well as delete an existing one. Notice that in order to delete, you must first use the directional controls on the device to highlight the note. Furthermore, selecting a note title from the list should bring up the note editor to let you edit it. Press confirm when finished to save the changes back to the database.
现在,你应该能从菜单增加真实的便签,也能删除存在的便签。注意:为了删除,你必须首先使用设备方向控制来选中便签。此外,从列表中选择便签标题应该被提出到便签编辑器,以便你能编辑他。按确认按钮保证保存修改到数据库中。
没有评论:
发表评论