Android学习资料之记事本应用程序开发练习2.ppt_第1页
Android学习资料之记事本应用程序开发练习2.ppt_第2页
Android学习资料之记事本应用程序开发练习2.ppt_第3页
Android学习资料之记事本应用程序开发练习2.ppt_第4页
Android学习资料之记事本应用程序开发练习2.ppt_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Android学习资料之记事本应用程序开发练习2,概述:记事本应用程序开发练习第一步记事本应用程序开发练习第二步记事本应用程序开发练习第三步记事本应用程序开发练习第四步开始其它Activities记事本应用程序开发练习第五步第六步第七步布局的艺术第八步第九步第十步第十一步至关重要的AndroidManifest文件第十二步答案和下一步的学习计划,在本练习中,你将学习如何添加第二个Activity至你的记事本应用程序中,该Activity可以让用户创建、编辑以及删除便笺。这个Activity假定通过用户的输入响应创建新便笺,并将其自身打包至一个由intent提供的Bundle返回值中。这个练习的目标是:构建一个新Activity并将其添加至Androidmanifest中通过异步调用方法startActivityForResult()来调用另一Activity用诸多Bundle对象在Activity之间传递数据如何使用一个更高级的屏幕布局,概述,用NotepadCodeLab文件夹下Notepadv2目录里的资源创建一个新Android工程,正如与练习一中做过类似的一样。如果你看到一个有关AndroidManifest.xml,或有关android.zip文件的错误信息,请右击工程选择AndroidToolsFixProjectProperties,即可修正错误。打开Notepadv2工程并查看如下内容:打开并查看res/values路径下的strings.xml文件里面有若干我们将要用于新功能的新字符串同时,打开并查看Notepadv2这个类的顶部,你将会注意到一个用于存放我们即将用到的新字段,指针mNotesCursor,其下已定义了几个新常量。,Android学习资料之第一步,还需注意的是方法fillData()已多了一些注释,并且现在用新定义的字段存储便笺指针。本练习中的方法onCreate()与练习一中的声明和实现相比并无变化。另需留意的是用于存储便笺指针的类成员变量叫做mNotesCursor。首字母m已表明该变量为一成员变量并符合Android编码风格标准。接下来还有几个我们将要实现的新覆写接口(onListItemClick()和onActivityResult()。,Android学习资料,添加一个删除一条便笺的菜单项:在接口onCreateOptionsMenu()中,添加如下一行代码:menu.add(0,DELETE_ID,0,R.string.menu_delete);该接口的完整定义如下:OverridepublicbooleanonCreateOptionsMenu(Menumenu)super.onCreateOptionsMenu(menu);menu.add(0,INSERT_ID,0,R.string.menu_insert);menu.add(0,DELETE_ID,0,R.string.menu_delete);returntrue;,Android学习资料之第二步,在接口onMenuItemSelected()中,为参数DELETE_ID添加一个新分支语句:mDbHelper.deleteNote(getListView().getSelectedItemId();fillData();returntrue;这里,我们通过接口deleteNote()删除指定ID的便笺。为了得到指定便笺的ID,我们调用接口getListView().getSelectedItemId().接下来,我们会调用接口fillData()以保持数据的更新.接口onMenuItemSelected()的完整定义如下:,Android学习资料之第三步,OverridepublicbooleanonMenuItemSelected(intfeatureId,MenuItemitem)switch(item.getItemId()caseINSERT_ID:createNote();returntrue;caseDELETE_ID:mDbHelper.deleteNote(getListView().getSelectedItemId();fillData();returntrue;returnsuper.onMenuItemSelected(featureId,item);,Android学习资料,在本例中,我们的intent用了一个特定名称的类。我们也可以创建Intents而不必清楚地知道控制此Intent的应用程序究竟是哪个,因为正如我们对类中的startingintents所了解的那样,该类既可以在我们自己的应用程序中也可以在另一应用程序中。例如,我们可能想打开一个浏览器中的一个页面,这里我们仍将用到一个Intent。但是我们用一个预先定义好的Intent常量和一个用于描述我们目的的URI内容,而非某一特定的类,来控制此Intent。,Android学习资料之第四步开始其它Activities,实现接口createNote():为创建一个便笺(ACTIVITY_CREATE)而用一个名为NoteEdit的类创建一个新Intent。紧接着调用接口startActivityForResult()来启动该Intent。:Intenti=newIntent(this,NoteEdit.class);startActivityForResult(i,ACTIVITY_CREATE);这种形式的Intent调用是面向我们Activity中特定类的,本例中该特定类即为NoteEdit。由于Intent类需要通过Android操作系统来发送请求信息,我们还得提供一个Context(this)。,Android学习资料,触发该Intent的接口startActivityForResult()是在一个新Activity完成后,才在我们的Activity中被调用的。在我们的Activity中用于接收回调的接口名为onActivityResult(),我们将在稍后的步骤中实现它。另一调用Activity的接口名为startActivity(),但这是一种一劳永逸的调用方式(fire-and-forget)在该调用方式下,当前的Activity并不会收到另一Activity已完成的通知,同时我们无法从被调Activity的接口startActivity()返回有关该Activity的任何结果信息。不必担心NoteEdit目前还不存在这一事实,我们很快就将完善之。,Android学习资料,实现覆写接口onListItemClick():onListItemClick()是一个我们将要覆写的回调函数。它在用户点击便笺列表中的某一项时调用。它一共有四个参数,分别是:调用该接口的ListView对象,所点击的View(存在于ListView中),所点击的position(该项在列表中的位置),所点击的某一项的行索引(mRowId)。在本例中我们先忽略前两个参数(当前我们只可能有一个ListView),以及参数行索引。我们的着眼点全在用户所选中的某一项在列表中所在的位置position。通过这个参数,我们可以从相应的行得到想要的数据,并将此数据打包发送至NoteEditActivity。,Android学习资料之第五步实现覆写接口onListItemClick(),在该回调函数接口的实现中,我们用类NoteEdit创建一个Intent来修改便笺内容,接着添加数据至一个作为参数传递给被调用Activity的Intent的附加包中。我们用其传递当前正在编辑的便笺的标题、正文以及行索引。最后,它将调用接口startActivityForResult()来启动该Intent。以下是接口onListItemClick()实现的完整代码:super.onListItemClick(l,v,position,id);Cursorc=mNotesCursor;c.moveToPosition(position);Intenti=newIntent(this,NoteEdit.class);,Android学习资料,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()是一个为触发Intent而添加数据至附加包中的接口。这里,我们用包传递我们想编辑的便笺内容的标题、正文以及行索引。,Android学习资料,当我们定位到所选择的对象所在列表中的相应位置时,通过接口moveToPosition(),有关该便笺的细节信息尽在查询指针中。通过添加到Intent的附加信息,及接口startActivityForResult(),我们在类NoteEdit中触发该Intent及请求类型码(请求类型码将作为参数requestCode返回给接口onActivityResult()。注意:我们在接口定义的开始处就将类成员变量mNotesCursor赋给一个局部变量。这可视为对Android应用程序代码的优化。因为访问一个局部变量其效率远高于访问Dalvik虚拟机中的一个类成员变量。所以通过这种方式处理,我们只需访问类成员变量一次,而访问局部变量五次,就可使得常规处理更高效。所以极力推荐尽可能用此方法优化你的Android应用程序代码。,Android学习资料,上述接口createNote()和onListItemClick()采用的是异步触发Intent的方式。我们得靠一个句柄来回调,所以以下是接口onActivityResult()的实现部分:onActivityResult()是一个只在一个Activity有返回结果时才被调用的覆写接口(记住!一个Activity只有在用接口startActivityForResult()启动时才有一个返回结果)。用于回调的一些参数如下:requestCode是Intent触发时确定的初始请求类型码(对我们而言,请求类型码无非就是ACTIVITY_CREATE或者ACTIVITY_EDIT这两者之一)。,Android学习资料之第六步,intent这是一个由Activity返回的结果创建的Intent。它用于在Intent中的Extras返回数据。接口startActivityForResult()和onActivityResult()的结合可视为一种异步的远程进程调用(RPC:RemoteProcedureCall),形成了一个Activity启动另一个Activity并彼此共享服务的推荐方式。以下为方法onActivityResult()完整的定义:super.onActivityResult(requestCode,resultCode,intent);Bundleextras=intent.getExtras();,Android学习资料,switch(requestCode)caseACTIVITY_CREATE:Stringtitle=extras.getString(NotesDbAdapter.KEY_TITLE);Stringbody=extras.getString(NotesDbAdapter.KEY_BODY);mDbHelper.createNote(title,body);fillData();break;caseACTIVITY_EDIT:LongmRowId=extras.getLong(NotesDbAdapter.KEY_ROWID);,Android学习资料,if(mRowId!=null)StringeditTitle=extras.getString(NotesDbAdapter.KEY_TITLE);StringeditBody=extras.getString(NotesDbAdapter.KEY_BODY);mDbHelper.updateNote(mRowId,editTitle,editBody);fillData();break;,Android学习资料,在本方法中我们既控制ACTIVITY_CREATE也控制ACTIVITY_EDIT的Activity结果。在请求类型码为创建的情况下,我们从extras(源于返回的Intent)得到便笺的标题和正文,并用这些创建一条新便笺。在请求类型码为编辑的情况下,我们除了从extras得到上述字段外,还有行索引,并用这些编辑并更新数据库中的便笺。fillData()最后的接口确保每一个都更新完毕。,Android学习资料,练习提供的屏幕布局文件note_edit.xml是我们将要建立的应用中最复杂的一个了,但这并不意味着你若想在真正的Android应用中用到一个布局,非得和这个有多接近才行。创建一个良好的界面是部分艺术、部分科学,剩余的就是孜孜以求了。掌握Androidlayout是创建一个赏心悦目的Android应用程序的核心部分。不妨看看ViewGallery中的一些例子,了解如何运用它们。范例工程ApiDemos是学习如何创建千姿百态的屏幕布局的极好资源。打开文件note_edit.xml并浏览一二,这是有关便笺编辑界面方面的代码。,Android学习资料之第七步布局的艺术,这是目前我们处理过的最复杂的界面布局了,这里给出的文件是为了避免在代码排版中出现淡入淡出的问题。(XML对大小写及结构有非常严格的限制,而这些错误往往又都是屏幕布局问题的根源所在。)这里用到了一个之前我们从未见过的新参数:android:layout_weight(在本例中该参数每种情况下都赋值为1)layout_weight用于给一个线性布局中的诸多视图的重要度赋值。所有的视图都有一个layout_weight值,默认为零,意思是需要显示多大的视图就占据多大的屏幕空间。若赋一个高于零的值,则将父视图中的可用空间分割,分割大小具体取决于每一个视图的layout_weight值以及该值在当前屏幕布局的整体layout_weight值和在其它视图屏幕布局的layout_weight值中所占的比率而定。,Android学习资料,举个例子:比如说我们在水平方向上有一个文本标签和两个文本编辑元素。该文本标签并无指定layout_weight值,所以它将占据需要提供的最少空间。如果两个文本编辑元素每一个的layout_weight值都设置为1,则两者平分在父视图布局剩余的宽度(因为我们声明这两者的重要度相等)。如果两个文本编辑元素其中第一个的layout_weight值设置为1,而第二个的设置为2,则剩余空间的三分之一分给第一个,三分之二分给第二个(因为我们声明第二个有较之第一个更高的重要度)。这个布局也演示了如何在其它布局中嵌套多个布局以实现更复杂更漂亮的布局。在本例中,一个水平方向上的线性布局嵌套在另一垂直方向上的布局中,以使标题标签和文本字段在水平方向上挨个对齐。,Android学习资料,创建一个NoteEdit类以扩展android.app.Activity。这是我们第一次不用AndroidEclipse插件的帮助来创建一个Activity。当按这种方式创建时,方法onCreate()并未自动覆写。很难想象一个没有覆写其onCreate()方法的Activity会是什么样子,所以这是接下来你先得完成的首要任务。右击Eclipse文件夹树形目录中的com.android.demo.notepad2文件夹,在弹出的右键菜单中选择NewClass。为类NoteEdit命一个名:对话框中的字段(fieldinthedialog)。,Android学习资料之第八步,在类Superclass中,输入android.app.Activity,也可以通过组合键(在Window和Linux环境下是Ctrl+Space,在Mac环境下则是Cmd+Space)来触发IDE中的代码提示以找到对应的文件夹和类。单击Finish。在生成的类中,在编辑窗口中单击右键,选择SourceOverride/ImplementMethods.。滑动对话框复选列表的滚动条定位到onCreate(Bundle)并选择紧邻的复选框。单击OK.这样方法就出现在你的类中了。,Android学习资料,为类NoteEdit的方法onCreate()实现其定义:该方法将为我们的新Activity设置一个名为”编辑便签”的标题(这是一个在文件strings.xml中定义的字符串),同时通过布局文件note_edit.xml设置便笺内容视图。我们可以得到便笺标题和文本正文视图,以及确认按钮的句柄。如此一来,我们就可以通过这些句柄设置得到便签的标题和正文,并将确认按钮绑定至响应用户按下该按钮的事件。然后,我们可以解开因传入于所调用的Intent中的附加包中,而已传到Activity里的参数值,并用这些值预填充标题和便签文本正文及视图,这样用户就可以编辑它们了。接下来,我们可以获取和存储便笺行索引(mRowId)这一值,从而可以知道用户当前正在编辑哪一条便签。,Android学习资料之第九步,在方法onCreate()中,建立布局:setContentView(R.layout.note_edit);找到我们需要的编辑和按钮组件可以通过在R类中声明的与之关联的ID找到这些资源,然后需要将它转换为正确的视图类型(两个文本视图为EditText类,确认按钮为Button类)mTitleText=(EditText)findViewById(R.id.title);mBodyText=(EditText)findViewById(R.id.body);ButtonconfirmButton=(Button)findViewById(R.id.confirm);需要注意的是mTitleText和mBodyText这两个是类成员变量(你得先在类中声明才能在此使用),Android学习资料,在类中声明一个私有类成员变量LongmRowId,用于存储当前的行索引值mRowId(如果有的话)在方法onCreate()中继续添加代码,用Intent附加数据包(如果出现的话)中的值初始化便笺标题、正文及行索引ID这些变量mRowId=null;Bundleextras=getIntent().getExtras();if(extras!=null)Stringtitle=extras.getString(NotesDbAdapter.KEY_TITLE);Stringbody=extras.getString(NotesDbAdapter.KEY_BODY);mRowId=extras.getLong(NotesDbAdapter.KEY_ROWID);,Android学习资料,if(title!=null)mTitleText.setText(title);if(body!=null)mBodyText.setText(body);我们将因触发Intent而设置到附加数据包中的标题和正文两个值从中抽取出来。我们也对文本的字段赋值实行非空保护(防止出现空字符串赋给文本字段的意外情况出现)。,Android学习资料,为按钮创建一个方法onClickListener():Listener也许是UI实现中让人倍感困惑的方面之一,但在本例中我们要实现的效果却很简单,就是在用户点确定按钮时调用onClick()方法。用其做一些事,并将便签被编辑后的一些值返回给Intent这一调用者。我们通过名为匿名的内部类来实现这一目的,这个类除非你之前见过,否则第一次看到确实会让人觉得有点晕。但是你确实需要将困惑的心态暂且抛开,因为将来有机会可以参看这一段代码,并将了解到如何创建一个Listener并将其关联至一个按钮(Listener是Java开发中一个常见的术语,尤其是在UI的设计实现中)。下面代码是一个空的Listener:confirmButton.setOnClickListener(newView.OnClickListener()publicvoidonClick(Viewview);,Android学习资料,在我们的Listener中完成方法onClick()的实现部分:当用户按下确定按钮,这个接口就会运行。我们希望该方法能获取被编辑的便签文本中的标题和文本字段,并且将这些数据放到一个作为返回值的包中,这样这些数据就可以被传递回最初触发这个NoteEditActivity的Activity中,如果该接口响应的是一个编辑而不是创建操作的话,我们还需将行行索引ID(rowed)也放至作为返回值的包中,这样Notepadv2类就可以保存对便签所做的编辑。,Android学习资料之第十步,创建一个作为返回值的数据包(Bundle)。并将便笺标题和正文这两个值,在Notepadv2中定义的关键字常量,传递给它Bundlebundle=newBundle();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);,Android学习资料,将此数据包传入一个新的Intent中并结束ActivityIntentmIntent=newIntent();mIntent.putExtras(bundle);setResult(RESULT_OK,mIntent);finish();这里的这个新Intent只是扮演一个简单的数据包传递者的角色(里面包括我们要传递的便笺标题、正文及行索引ID)方法setResult()是设置结果类型码并将Intent传递回此Intent的调用者。在本例中,每个都奏效了,所以我们返回的结果编码为RESULT_OK。,Android学习资料,调用方法finish()是标识该Activity已完成的信号(相当于一个返回调用)。任何设置到结果中的接口都和执行控制信息一并返回至结果调用者。方法onCreate()(另加支持该类的一些字段)的完整实现如下:privateEditTextmTitleText;privateEditTextmBodyText;privateLongmRowId;Override,Android学习资料,protectedvoidonCreate(BundlesavedInstanceState)super.onCreate(savedInstanceState);setContentView(R.layout.note_edit);mTitleText=(EditText)findViewById(R.id.title);mBodyText=(EditText)findViewById(R.id.body);ButtonconfirmButton=(Button)findViewById(R.id.confirm);mRowId=null;Bundleextras=getIntent().getExtras();,Android学习资料,if(extras!=null)Stringtitle=extras.getString(NotesDbAdapter.KEY_TITLE);Stringbody=extras.getString(NotesDbAdapter.KEY_BODY);mRowId=extras.getLong(NotesDbAdapter.KEY_ROWID);if(title!=null)mTitleText.setText(title);if(body!=null)mBodyText.setText(body);,Android学习资料,confirmButton.setOnClickListener(newView.OnClickListener()publicvoidonClick(Viewview)Bundlebundle=newBundle();bundle.putString(NotesDbAdapter.KEY_TITLE,mTitleText.getText().toString();bundle.putString(NotesDbAdapter.KEY_BODY,mBodyText.getText().toString();,Android学习资料,if(mRowId!=null)bundle.putLong(NotesDbAdapter.KEY_ROWID,mRowId);IntentmIntent=newIntent();mIntent.putExtras(bundle);setResult(RESULT_OK,mIntent);finish(););,Android学习资料,AndroidManifest.xml文件是Android操作系统理解你应用程序的方式。此文件定义了在启动和设置时在何处(或者是否)显示应用程序、该应用程序定义了哪些活动(acivities)、服务(services)和内容提供者(ContentProviders)、以及该应用程序能接收哪些Intent等等诸如此类的应用程序分类目录。最后,在manifest文件中定义了新的Activity:在新Activity被Android操作系统识别之前,它需要在AndroidManifest.xml文件中有自己的Activity入口(ActivityEntry)。这样Android操作系统就知道该Activity在AndroidManifest.xml文件中并可以被其调用。我们也可以确定该Activity在此处

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论