Android与MVC设计模式
在本章中,您将升级GeoQuiz应用程序,让应用能够提供更多的测试题目,如图2-1所示。
图2-1 更多测试题目
窗体底端
为了实现这一点,你将要添加一个名为TrueFalse的类到GeoQuiz项目。 这个类的一个实例将封装一个单一的真假问题。
然后,您将创建一个TrueFalse对象数组,以便QuizActivity进行管理。
创建新类
在软件包资源管理器中,右键单击com.bignerdranch.android.geoquiz软件包,然后选择New → Class。将类命名为TrueFalse,保持默认的超类java.lang.Object 不变,然后单击Finish按钮。
图2-2 创建TrueFalse类
在TrueFalse.java中,新增两个成员变量和一个构造函数,如代码清单2-1所示。
清单2-1 添加到TrueFalse类(TrueFalse.java)
为什么mQuestion是int而不是String? mQuestion变量将保存该问题的字符串资源的资源ID(始终为int)。您将在后面的部分中创建问题字符串资源。mTrueQuestion变量指示语句是真还是假。
这些变量需要getter和setter方法。为避免手工输入,您可以设置由Eclipse自动生getter与setter方法。
生成getter与setter方法
首先,配置Eclipse识别成员变量的m前缀,并且对于boolean类型的成员变量使用is而不是get前缀。
打开Eclipse的首选项( Mac 用户选择Eclipse 菜单,Windows 用户选择Windows →Preferences菜单)。 在Java首选项下,选择Code Style。
在Conventions for variable names:表中,选择Fields行(图2-3)。单击Edit按钮,并添加m作为fields的前缀。 然后将s添加为Static Fields的前缀。 (您将不会在GeoQuiz项目中使用s前缀,但在以后的项目中会用到。)
确认Use lsquo;isrsquo; prefix for getters that return boolean选择框被勾选后,单击OK按钮,如图2-3所示。
图2-3 设置Java代码样式首选项
设置这些前缀的要点是什么? 现在,当你要求Eclipse为mQuestion生成一个getter时,生成的是getQuestion()而不是getMQuestion();而在为mTrueQuestion生成getter方法时,生成的则是isTrueQuestion() 而不是isMTrueQuestion()方法。
返回TrueFalse.java,右键单击构造函数,然后选择Source→Generate Getters And Setters ...单击Select All按钮,为每个变量创建一个getter和setter方法。
单击确定,Eclipse将生成四种方法的代码,如代码清单2-2所示。
代码清单2-2 生成getter与setter方法(TrueFalse.java)
这样TrueFalse类就完成了。稍后,我们将修改QuizActivity类来配合TrueFalse类的使用。首先,我们来了解一下GeoQuiz应用,看看各个类将如何协同工作。
你将要使用QuizActivity创建一个TrueFalse对象的数组。 然后它会与TextView和三个按钮交互,显示问题并提供有关用户响应的反馈,如图2-4所示。
图2-4 GeoQuiz应用对象图解
Android 与MVC 设计模式
如图2-4所示,应用的对象分为Model,Controller和View的三个部分。Android应用是基于Model-View-Controller的架构进行设计,或者简称为MVC。MVC设计模式表明,应用程序中的任何对象必须是模型对象、视图对象或控制器对象中的一种。
bull;模型对象存储着应用的数据和业务逻辑。模型类通常用于对应用程序关注的内容进行建模,例如用户、商店中的产品、服务器上的照片或电视节目。又或是GeoQuiz应用里的问题。模型对象不关心用户界面; 它唯一的目的是存储和管理数据。
在Android应用程序中,模型类通常是我们创建的自定义类。应用程序中的所有模型对象组成其模型层。
GeoQuiz的模型层由TrueFalse类组成。
bull;视图对象知道如何在屏幕上绘制自己,以及如何响应用户输入(如触摸)。一个简单的经验法则是,凡是可以在屏幕上看到的对象,都是视图对象。
Android提供了大量可配置的视图类。您还可以创建自定义视图类。应用程序的视图对象组成其视图层。
GeoQuiz的视图层由从activity_quiz.xml文件中定义的各类组件构成的。
bull;控制器对象将视图和模型对象绑定在一起。它们包含“应用程序逻辑”。控制器旨在响应由视图对象触发的各种事件,并管理与模型对象和视图层之间的数据流。
在Android中,控制器通常是Activity、Fragment或Service的一个子类。(第7章和第29章将分别介绍fragment和service的概念。)
GeoQuiz的控制器层目前仅由QuizActivity组成。
图2-5显示了在响应用户单击按钮等事件时,对象间的交互控制数据流,例如按下按钮。请注意,模型和视图对象不直接交互; 控制器作为它们间的联系纽带,从一些对象接收消息并向其他对象发送指令。
图2-5 MVC 数据控制流与用户交互
使用MVC设计模式的好处
随着应用功能的持续扩展,应用往往会变得过于复杂而让人难以理解。将代码分成类可以帮助您设计和了解整个应用程序;这样,可以根据类而不是单个变量和方法来思考设计开发问题。
类似地,将类分离为模型、视图和控制器层可帮助您设计和理解应用程序;你可以考虑层次而不是单独的类。
GeoQuiz不是一个复杂的应用程序,但以MVC分层模式设计它的好处还是显而易见的。稍后,我们来更新GeoQuiz的视图层,并为它添加一个Next按钮。这样做时,我们会发现,在添加Next按钮的过程中,可完全不用考虑刚才创建的TrueFalse类的存在。
使用MVC模式还可以让类的复用更加容易。相比功能多而全的类,有特别功能限定的专用类更加有利于代码的复用。
举例来说,模型类TrueFalse与用作显示问题的组件毫无代码逻辑关联。这使您可以轻松地在整个应用程序中使用TrueFalse来实现不同的目的。例如,如果您想一次显示所有问题的列表,直接复用TrueFalse对象逐条显示就可以了。
更新视图层
了解了MVC设计模式后,现在让我们来更新GeoQuiz的视图层,为其添加一个Next按钮。
在Android中,视图层中的对象通常会在XML的布局文件生成。GeoQuiz中的唯一布局在activity_quiz.xml中定义。此布局需要更新,如图2-6所示。(请注意,为节约版面,我们未显示未更改的小部件。)
图2-6 新增的按钮
因此,您需要对视图层进行更改:
bull;删除TextView中android:text属性定义。这里不再需要硬编码问题。
bull;给TextView新增android:id属性。TextView组件需要一个资源ID,以便在QuizActivity代码中为它设置文本。
bull;以根LinearLayout为父组件,新增一个Button组件。
返回到activity_quiz.xml文件中,参照代码清单2-3完成XML文件的相应修改。
代码清单2-3 新增按钮以及文本视图的调整(activity_quiz.xml)
保存activity_quiz.xml文件,您可能会看到一个熟悉的错误弹出来提醒您有关一个缺少的字符串资源。
返回到res/values /strings.xml文件中。删除问题字符串并添加新的按钮的字符串资源定义,如代码清单2-4所示。
代码清单2-4 更新字符串资源定义(strings.xml)
保持strings.xml文件处于打开状态,请继续添加将显示给用户的一组地理问题的字符串。如代码清单2-5所示。
代码清单2-5 新增问题字符串(strings.xml)
注意最后一行字符串定义中的“”,这里,我们使用了转义字符对符号“”进行了处理。也可使用其他常见的转义字符,比如 新行符。
保存文件。然后返回到activity_quiz.xml文件中,并在图形布局工具里预览确认修改后的布局文件。
这就是GeoQuiz的视图层。接下来,我们对控制层的QuizActivity 类进行代码编写与资源引用,从而最终完成QeoQuiz应用。
更新控制层
在上一章中,GeoQuiz应用控制层的QuizActivity类的处理逻辑很简单。它显示了在activity_quiz.xml文件中定义的布局对象。它通过在两个按钮上设置监听器,响应用户点击事件并创建提示消息。
现在您有多个检索和显示的问题,QuizActivity类将不得不更加努力地将GeoQuiz的模型层和视图层结合在一起。
打开QuizActivity.java文件。为TextView添加变量和新的Button。另外,创建一个TrueFalse对象数组和数组的索引,如代码清单2-6所示。
代码清单2-6 增加按钮变量及TrueFalse对象数组(QuizActivity.java)
在这里,您可以通过多次调用TrueFalse类的构造函数,创建一个TrueFalse对象数组。
(在一个更复杂的项目中,这个数组将被创建并存储在其他地方,在本书后续应用开发中,您将看到更好的存储模型数据的选项。现在,我们保持简单,只需在控制器中创建数组。
通过使用mQuestionBank数组、mCurrentIndex变量和TrueFalse对象中的存取方法来获取屏幕上的问题。
首先,获取TextView的参考,并将其文本内容设置为当前数组索引的问题。如代码清单2-7 所示。
代码清单2-7 使用TextView(QuizActivity.java)
保存文件并检查是否有任何错误。然后运行GeoQuiz应用。您应该会看到数组中的第一个问题出现在TextView中。
现在来看看Next按钮。首先,获取对Next按钮的引用。然后设置一个View.OnClickListener就可以了。该监听器的作用是:递增数组索引并相应更新显示TextView的文本内容。如代码清单2-8所示。
代码清单2-8 使用新增按钮(QuizActivity.java)
现在,您可以在更新mQuestionTextView变量的两个不同的地方添加代码。花一点时间把公共代码放在单独的私有方法里,如表2-9所示。 然后在mNextButton的监听器中和onCreate(Bundle)方法的末尾调用该方法,以初始设置activity视图中的
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[140556],资料为PDF文档或Word文档,PDF文档可免费转换为Word
课题毕业论文、外文翻译、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。