此 Codelab 是“Android Kotlin 基础知识”课程的一部分。如果您按顺序学习这些 Codelab,您将会充分发掘此课程的价值。“Android Kotlin 基础知识”Codelab 着陆页列出了所有课程 Codelab。
在此 Codelab 中,您将学习 fragment,它表示 activity 中界面的一种行为或某一部分。您需要在一个名为 AndroidTrivia 的有趣起始应用中创建一个 fragment。在下一个 Codelab 中,您将详细学习导航,并进一步开发 AndroidTrivia 应用。
您应当已掌握的内容
- Kotlin 的基础知识
- 如何使用 Kotlin 创建基本 Android 应用
- 如何使用布局
学习内容
- 如何向应用静态添加 fragment
实践内容
- 在 activity 内创建 fragment。
在构成本课程的三个 Codelab 中,相关操作是在一个名为 AndroidTrivia 的应用中完成的。这个已完成的应用是一款游戏,用户需要在游戏中回答三个有关 Android 编码的知识问答题。如果用户正确回答了所有三个问题,就会赢得游戏并且可以分享游戏结果。
AndroidTrivia 应用旨在用于介绍导航模式和控件。该应用包含以下几个组件:
- 如上方左侧屏幕截图所示,在游戏名屏幕中,用户开始游戏。
- 如上方中间屏幕截图所示,在显示问答题的游戏屏幕中,用户参与游戏并提交答案。
- 如上方右侧屏幕截图所示,抽屉式导航栏从应用侧面滑出,其中包含一个带有标题的菜单。抽屉式导航栏图标 可用于打开抽屉式导航栏。抽屉式导航栏菜单包含一个指向“About”页面的链接和一个指向游戏规则的链接。
应用的顶部显示一个名为 *应用栏(*或操作栏)的视图,用于显示应用的名称。
在此 Codelab 中,您将使用一个初始应用,该应用提供了完成 Trivia 应用所需的模板代码和 fragment 类。
- 下载 AndroidTrivia-Starter Android Studio 项目。您可能需要下载整个 android-kotlin-basic-starter-apps ZIP 文件。
- 在 Android Studio 中打开项目并运行应用。当应用打开时,除了显示应用名称和空白屏幕,不执行任何其他操作。
- 在 Android Studio 的“Project”窗格中,打开“Project: Android”视图以浏览项目文件。打开 app > java 文件夹,查看
MainActivity
类和 fragment 类。
- 打开 res > layout 文件夹,然后双击 activity_main.xml。
activity_main.xml
文件会显示在布局编辑器中。 - 打开 Design 标签页。
activity_main.xml
文件对应的 Component Tree 将根布局显示为垂直LinearLayout
。
在垂直线性布局中,布局中的所有子视图均垂直对齐。
Fragment
表示 Activity
中界面的一种行为或某一部分。您可以将多个 fragment 组合在一个 activity 中来构建多窗格界面,也可以在多个 activity 中重复使用一个 Fragment
。
可以将 Fragment
视为 activity 的一个模块化部分,就像您也可以在其他 activity 中使用的子 activity 一样:
Fragment
有自己的生命周期,会接收自己的输入事件。- 您可以在 activity 运行期间添加或移除
Fragment
。 Fragment
在 Kotlin 类中定义。- fragment 的界面在 XML 布局文件中定义。
AndroidTrivia 应用有一个主 activity 和几个 fragment。大部分 fragment 及其布局文件均已为您预先定义。在此任务中,您需要创建一个 fragment,并将 fragment 添加到应用的主 activity 中。
第 1 步:添加 fragment 类
在此步骤中,您需要创建一个空白 TitleFragment
类。首先,为新 fragment 创建一个 Kotlin 类:
- 在 Android Studio 中,点击“Project”窗格内的任意位置,使焦点返回到项目文件中。例如,点击 com.example.android.navigation 文件夹。
- 依次选择 File > New > Fragment > Fragment (Blank)。
- 对于 fragment 名称,请输入 TitleFragment。
- 对于 fragment 布局名称,请输入 placeholder_layout(我们不会对应用使用该布局,因为它已有为 TitleFragment 设计的布局)。
- 对于源语言,请选择 Kotlin。
- 点击 Finish。
- 打开
TitleFragment.kt
fragment 文件(如果尚未打开)。它包含onCreateView()
方法,这是在 fragment 的生命周期中调用的方法之一。 - 删除
onCreateView()
内的代码。onCreateView()
函数只保留以下代码:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
}
- 在
TitleFragment
类中,删除onCreate()
方法、fragment 初始化参数和伴生对象。确保您的TitleFragment
类如下所示:
class TitleFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
}
}
创建绑定对象
fragment 目前无法编译。为了进行 fragment 编译,您需要创建一个绑定对象并膨胀 fragment 的视图(等同于对 activity 使用 setContentView()
)。
- 在
TitleFragment.kt
的onCreateView()
方法中,创建一个binding
变量 (val binding
)。 - 如需膨胀 fragment 的视图,请对 fragment 的
Binding
对象(即FragmentTitleBinding
)调用DataBindingUtil.inflate()
方法。
将四个参数传递到 DataBindingUtil.inflate
方法:
inflater
,用于膨胀绑定布局的LayoutInflater
。- 要膨胀的布局的 XML 布局资源。请使用已为您预先定义的布局之一
R.layout.fragment_title
。 - 用于父级
ViewGroup
的container
。(此参数是可选的。) - 用于
attachToParent
值的false
。
- 将
DataBindingUtil.inflate
返回的绑定分配给binding
变量。 - 从包含膨胀视图的方法中返回
binding.root
。您的onCreateView()
方法现在类似于以下代码:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val binding = DataBindingUtil.inflate<FragmentTitleBinding>(inflater,
R.layout.fragment_title,container,false)
return binding.root
}
- 打开 res>layout 并删除
placeholder_layout.xml
。
第 2 步:将新的 fragment 添加到主布局文件
在此步骤中,您需要将 TitleFragment
添加到应用的 activity_main.xml
布局文件中。
- 依次打开 res > layout > activity_main.xml,然后选择 Code 标签页,以查看布局 XML 代码。
- 在现有
LinearLayout
元素内,添加fragment
元素。 - 将 fragment 的 ID 设置为
titleFragment
。 - 将 fragment 的名称设置为 fragment 类的完整路径,在本例中为
com.example.android.navigation.TitleFragment
。 - 将布局宽度和高度设置为
match_parent
。
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="@+id/titleFragment"
android:name="com.example.android.navigation.TitleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
</layout>
- 运行应用。fragment 已添加到主屏幕。
Android Studio 项目:AndroidTriviaFragment
提醒:确保使用最新版本的 fragment (androidx.fragment.app.Fragment)。旧版本的 fragment 在 API 级别 28 中已弃用。
在此 Codelab 中,您向 AndroidTrivia 应用添加了一个 fragment,在本课的后续两个 Codelab 中您将继续在此应用中执行操作。
- fragment 是 activity 的模块化部分。
- fragment 有自己的生命周期,会接收自己的输入事件。
- 使用
<fragment>
标签在 XML 布局文件中为 fragment 定义布局。 - 膨胀
onCreateView()
中 fragment 的布局。 - 您可以在 activity 运行期间添加或移除 fragment。
Udacity 课程:
Android 开发者文档:
此部分列出了在由教师指导的课程教学中,学生完成此 Codelab 后可能需要做的家庭作业。教师自行决定是否执行以下措施:
- 根据需要布置作业。
- 告知学生如何提交家庭作业。
- 给家庭作业评分。
教师可以酌情采用这些建议,并且可以自由布置自己认为合适的任何其他家庭作业。
如果您是在自学此 Codelab,可随时通过这些家庭作业来检测您的知识掌握情况。
回答以下问题
问题 1
fragment 和 activity 之间有哪些区别?请选择所有正确的表述。
- 创建 fragment 时,您需要在
onCreateView()
方法中膨胀布局。创建 activity 时,您需要在onCreate()
中膨胀布局。 - activity 有自己的布局,但 fragment 不能有自己的布局。
- activity 有自己的生命周期,但 fragment 没有。
- 为 fragment 或 activity 膨胀布局时,您可以用
R.layout.
layoutname
的形式引用布局。
问题 2
以下关于 fragment 的表述中哪些是正确的?请选择所有适用的选项。
- 您可以在多个 activity 中使用同一个 fragment。
- 一个 activity 可以有多个 fragment。
- 在 Kotlin 类中定义 fragment 后,系统会自动将 fragment 添加到
activity_main.xml
布局文件中。 - 使用
<fragment>
标签来定义布局文件中要插入 fragment 的位置。
开始学习下一课:
如需本课程中其他 Codelab 的链接,请参阅“Android Kotlin 基础知识”Codelab 着陆页。