1.实验目的
(1)掌握使用RadioButton和Fragment实现导航栏的方式。
(2)熟悉Selector(选择器)的用法。
(3)掌握Fragment和FragmentStatePager Adapter的用法。
2.Selector
Selector在Android中常用于控件在不同状态下外观的设置,如为按钮、Tab标签页、List View中的一个选项的不同状态设置不同的颜色、图片,这样省去了用代码控制控件在不同状态下使用不同的背景颜色或图片。Selector是drawable目录下的XML文件,以selector为根标签,在item子标签中定义不同状态下的颜色或图片等。例如:
上述配置文件的含义为当前控件处于选中状态时使用pic1,否则使用pic2。Selector常用的控件状态有以下几种。
•android:state_pressed:当取值为true,即被按压时,显示item中定义的图片或颜色,取值为false,即未被按压时,则显示默认。
•android:state_focused:当取值为true,即获得焦点时,显示item中定义的图片或颜色,取值为false,即没有获得焦点时,则显示默认。
•android:state_selected:当取值为true,即被选择时,显示item中定义的图片或颜色,取值为false,即未被选择时,则显示默认。
•android:state_checkable:当取值为true,即能选中时,显示item中定义的图片或颜色,取值为false,即不能选中时,则显示默认。
•android:state_checked:当取值为true,即被选中时,显示item中定义的图片或颜色,取值为false,即未被选中时,则显示默认。
•android:state_enabled:当取值为true,即该控件能使用时,显示item中定义的图片或颜色,取值为false,即该控件不能使用时,则显示默认。
•android:state_window_focused:设置当前窗口是否获得焦点状态,取值为true表示获得焦点,取值为false表示未获得焦点。例如,拉下通知栏或弹出对话框时,当前界面就会失去焦点。
3.Fragment
Fragment是Android 3.0(API 11)提出的控件,可看作一个轻量级的Activity,又称Activity的片段。Fragment具有以下特点:
(1)使用Fragment必须继承自Fragment这个类。
(2)同一个Fragment可放置到多个不同的Activity中,同一个Activity也可以动态加载不同的Fragment。
(3)Fragment有自己的布局文件,其布局文件和Activity的布局文件相同。
(4)Fragment不能独立运行,必须放入Activity中才能被加载。
(5)Fragment有自己的布局和生命周期回调函数。
Fragment的生命周期回调函数与所归属的Activity同步,具体如图2.53所示。Fragment特有的生命周期回调函数如下所示。
•on Attach(Activity):当所归属的Activity与Fragment发生关联时调用。
•onCreate View(LayoutInflater,View Group,Bundle):创建该Fragment的视图。该方法是最常用的方法。
图2.53 Fragment和Activity的生命周期回调函数
•on ActivityCreate(bundle):当所归属的Activity的onCreate()方法返回时调用。
•on Destroy View():与onCreate View()相对应,当该Fragment被移除时调用。
•on Detach():与on Attach()相对应,当Fragment与Activity的关联被取消时调用。
Fragment创建步骤为:创建Fragment的布局文件;自定义Fragment类,使其继承自Fragment,在其中绑定Fragment的视图;编写Fragment中控件的触发事件。
在Activity中动态加载Fragment还需要两个常用类,分别是:android.app.Fragment Manager(主要用于在Activity中操作Fragment)和android.app.Fragment Transaction(对Fragment进行增加、删除等操作)。Activity的getFragment Manager()方法可返回Fragment Manager对象,Fragment Manager对象的begin Transaction()方法即可返回Fragment Transaction对象,Fragment Transaction对象的add()方法可用于添加Fragment。代码如下所示。
4.实验界面与功能
图2.54是常用的导航栏界面,点击界面下方的按钮分别加载不同的Fragment,用户界面可以放在Fragment中实现。
图2.54 导航栏界面
5.工程结构
本实验有5个Java类,包括1个Activity和4个Fragment,与之对应的有5个布局文件。导航栏有4个选项,4个选项分为选中和未选中状态,所以本实验有8张图片。每组图片选中和未选中状态的切换通过Selector实现,文字颜色的变化也通过Selector实现,所以在drawable目录下有5个selector文件,工程结构如图2.55所示。
6.实验步骤
步骤1:新建工程App07,Java代码类名和布局文件名保持默认。
步骤2:在strings.xml文件中增加常量字符串。
图2.55 App07工程结构
步骤3:在colors.xml文件中定义工程中用到的颜色,分别取值如下。
步骤4:复制图片至mipmap目录下,在drawable目录下为图片生成4个selector文件,以“发现”按钮为例,该按钮状态对应的selector_tab_find.xml文件内容如下所示。
上述文件意为:当采用该配置文件的控件处于选中状态时采用tab_find_selected.png,否则采用tab_find_normal.png。请根据上述文件自行编写selector_tab_home.xml、selector_tab_profile.xml和selector_tab_search.xml文件。
步骤5:导航栏的按钮被选中时文字为白色,未被选中时文字为黄色,这两种颜色的切换也是通过Selector来设置的,对应的文件为drawable目录下的selector_tab_text_color.xml,内容如下所示。
步骤6:打开activity_main.xml文件,删除默认的文本控件。在可视化视图的Component Tree中按图2.56所示拖入一个Frame Layout,用于放置Fragment,当用户选中不同的导航按钮后,将加载不同的Fragment。将该Frame Layout的ID更改为homeContent,并根据图2.57所示定义高度和宽度。在FrameLayout下面拖入一个RadioGroup控件,在可视化视图中设置约束。另外,在文本视图中设置RadioGroup与外边框同宽,高度为58 dp,背景色为步骤3中定义的tab_bg,方向为水平放置。在该控件中放入4个RadioButton,以下是“首页”按钮的布局文件内容,请仿照该按钮完成其他按钮的设计。RadioButton是单选按钮,是Android开发中常用的按钮。一组互斥的单选按钮必须放在RadioGroup容器中。默认的RadioButton图片是,本实验采用自定义的图片作为按钮图片。
(www.xing528.com)
图2.56 activity_main.xml布局
图2.57 FrameLayout属性值
步骤7:在layout目录下建立4个Fragment的布局文件,用于点击不同的选项后加载的不同Fragment。将4个Fragment的布局文件命名为fragment_home.xml、fragment_find.xml、fragment_profile.xml和fragment_search.xml。4个文件可采用任意布局。在4个布局文件中各放入一个Text View,Text View中设置不同的文字,方便观察界面的切换。具体内容请读者自行完成。
步骤8:新建4个类,使其继承自Fragment,分别将其命名为HomeFragment.java、Find Fragment.java、ProfileFragment.java和Search Fragment.java。在该类中重载onCreateView()方法用于初始化界面,重写set Menu Visibility()方法用于设置视图可见情况的切换。以“首页”按钮加载的HomeFragment为例,代码如下:
步骤9:打开Main Activity.java文件,在文件中定义步骤6中的所有控件,控件的初始化代码封装在init View()中,并且定义常量NUM_ITEMS用于表示有4个选项。
步骤10:完成视图的初始化方法init View()。
步骤11:根据选择的Fragment更新homeContent。
步骤12:在Main Activity.java中定义Fragment的Adapter,用Adapter来管理4个Fragment界面的变化,这里用的Fragment是v4包里面的类。
步骤13:导航栏中的4个选项实质上是4个单选按钮,4个按钮在被点击之前和上方的Fragment是没有任何联系的,所以在加载视图时需要设置按钮和Fragment的关系,否则默认4个Fragment全部自动加载。具体做法是在Main Activity.java中增加onStart()方法,即界面可见时加载默认Fragment,从而避免了4个Fragment一起加载的现象。
步骤14:运行并测试App07。
知识拓展:gradle文件
Android Studio采用了Gradle作为构建工具,它使用Groovy语言来声明项目设置,避免了Ant和Maven中采用的XML语言的各种烦琐配置。通常只有一个模块的Android项目中有3个Gradle插件的配置文件,包括项目的build.gradle文件、模块的build.gradle文件和settings.gradle文件。
(1)项目的build.gradle文件:该文件内容如图2.58所示,该脚本文件默认由buildscript{}和allprojects{}两个脚本块以及一个清理任务组成。
图2.58 项目的build.gradle文件
①buildscript{}:设置的是Gradle脚本执行所需依赖。使用了repositories{}这个方法的闭包,调用了jcenter()方法,这个方法会访问JCenter远程仓库,设置之后可以在项目中轻松引用JCenter上的开源项目。在工程构建过程中如果缺少依赖,就会在远程仓库中查找,如果引用的依赖不在JCenter远程仓库中,用户需要自行添加,常用的有mavenCentral()、google()等。dependencies{}中声明了Android Studio使用的Gradle插件的版本号。dependencies{}的Gradle版本可通过Project Structure的Project设置和查看,如图2.59所示。
图2.59 Project Gradle设置
②allprojects{}:配置项目远程仓库。例如,项目中需要调用阿里云的Maven仓库,那么需要增加“maven{url https://maven.aliyun.com/repository/jcenter}”,这样在模块的build.gradle文件中即可访问该仓库,调用相关依赖。
③task clean(type:Delete){}:每次构建时需要清理的目录。
(2)模块的build.gradle文件如图2.60所示。
图2.60 模块的build.gradle文件
①apply plugin:’com.android.application’:表示这是一个应用程序模块,可直接运行。如果取值为“com.android.library”,则表示这是一个库模块,是依附于其他的应用程序而运行的,或者是被调用才能运行的。
②compileSdk Version:编译时用的SDK版本。
③build Tools Version:Build工具的版本。
④defaultConfig:默认配置。动态配置在Android Manifest.xml文件中的设置,defaultConfig里的配置可以覆盖manifest文件里的配置。
⑤applicationId"cn.edu.android.app09":应用程序的包名。
⑥testInstrumentation Runner"android.support.test.runner.AndroidJUnit Runner":设置Instrumentation单元测试。
⑦build Types:配置如何构建和打包当前App,默认有debug和release两种版本。debug版本包含调试时的信息,并且用debug key签名。release版本默认是不含签名的。图2.60中release版本用了proguard代码混淆。
⑧minify Enabled false:是否对代码进行混淆,“true”表示进行混淆代码。
⑨proguard Files get DefaultProguard File(proguard-android.txt),proguard-rules.pro:指定混淆时使用的规则文件,proguard-android.txt指所有项目通用的混淆规则,proguard-rules.pro指当前项目特有的混淆规则,release版本中proguard默认为Module下的proguard-rules.pro文件。
⑩dependencies:配置此模块的依赖包。Android Studio 3.0之前的版本中用compile引入依赖包,升级到3.0之后,Gradle版本也随之升级到3.0.0版本,在新版本中使用implementation。
•implementation file Tree(include:[*.jar],dir:libs):本地依赖,编译模块时会引入模块下libs目录下所有的依赖包,开发者如果需要引用第三方的jar包和arr包,仅需将它们复制至该目录下。
•implementation com.android.support:appcompat-v7:28.0.0:引用依赖appcompat,包路径为com.android.support,版本号为v7:28.0.0,用户在使用第三方依赖时,需要在dependencies标签中增加类似引用。当用户在Project Structure中增加依赖,可通过搜索功能在JCenter等仓库中进行搜索,例如,搜索“gson”后会出现多个版本,选中需要的版本,单击“OK”按钮,则dependencies会增加对gson的依赖,如图2.61所示。当构建版本时,会去JCenter仓库中下载相关jar包至C:\Users\用户名\.gradle\caches\modules-2\files-2.1目录。
图2.61 通过Project Structure搜索和增加依赖
•testImplementation junit:junit:4.12:声明测试用例采用JUnit及其版本号。
(3)settings.gradle文件:include:app中的“app”指明要构建的模块名。如图2.62所示,当前项目中有两个模块,即app和App01,该文件可以直接修改,可以增加或者删除一个模块,修改后单击同步按钮即可生效。这里删除模块并非从物理上删除,只是从项目中删除该模块。
(4)当对以上3个文件进行修改后,文件上方会出现“Sync Now”的提示,单击该按钮Gradle会同步该文件。
图2.62 settings.gradle文件
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。