Android Kotlin 基础知识 03.1:创建 Fragment

此 Codelab 是“Android Kotlin 基础知识”课程的一部分。如果您按顺序学习这些 Codelab,您将会充分发掘此课程的价值。“Android Kotlin 基础知识”Codelab 着陆页列出了所有课程 Codelab。

在此 Codelab 中,您将了解 fragment,并在名为 AndroidTrivia 的起始应用内创建一个 fragment。在下一个 Codelab 中,您将详细学习导航,并进一步开发 AndroidTrivia 应用。

您应当已掌握的内容

  • Kotlin 的基础知识
  • 如何使用 Kotlin 创建基本 Android 应用
  • 如何使用布局

学习内容

  • 如何向应用静态添加 fragment

您将执行的操作

  • 在 activity 内创建一个 fragment。

在构成本课程的三个 Codelab 中,相关操作是在一个名为 AndroidTrivia 的应用中完成的。这个已完成的应用是一款游戏,用户需要在游戏中回答三个有关 Android 编码的知识问答题。如果用户能正确回答全部三个问题,就可以在游戏中胜出并分享结果。

AndroidTrivia 应用旨在用于介绍导航模式和控件。该应用包含以下几个组件:

  • 如上方屏幕截图左侧的标题屏幕所示,用户开始了游戏。
  • 如上方中间屏幕截图所示,在显示问答题的游戏屏幕中,用户参与游戏并提交答案。
  • 如上方右侧屏幕截图所示,抽屉式导航栏从应用侧面滑出,其中包含一个带有标题的菜单。抽屉式导航栏图标 可用于打开抽屉式导航栏。抽屉式导航栏菜单包含一个指向“About”页面的链接和一个指向游戏规则的链接。

应用顶部会显示一个彩色视图,称为应用栏(也称为操作栏)。

在此 Codelab 中,您将使用入门级应用,该应用可为您提供完成知识问答应用时所需的模板代码和 fragment 类。

  1. 下载 AndroidTrivia-Starter Android Studio 项目。
  2. 在 Android Studio 中打开项目并运行应用。应用打开后,除了显示应用名称和空白屏幕,它不会执行其他操作。


  3. 在 Android Studio 的“Project”窗格中,打开“Project: Android”视图以浏览项目文件。打开 app > java 文件夹以查看 MainActivity 类和 fragment 类。

  4. 打开 res > layout 文件夹,然后双击 activity_main.xmlactivity_main.xml 文件会显示在布局编辑器中。
  5. 点击 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 类:

  1. 在 Android Studio 中,点击“Project”窗格内的任意位置,使焦点返回到项目文件中。例如,点击 com.example.android.navigation 文件夹。
  2. 依次选择 File > New > Fragment > Fragment (Blank)
  3. 对于 fragment 名称,请使用 TitleFragment。清除所有复选框,包括 create Layout XMLinclude fragment 工厂方法include interface callback
  4. 点击 Finish
  5. 打开 TitleFragment.kt fragment 文件(如果尚未打开)。它包含 onCreateView() 方法,这是在 fragment 生命周期期间调用的一种方法。
  6. onCreateView() 中,移除 return TextView(activity).apply 部分,包括以 setText 开头的行。onCreateView() 函数仅有以下代码:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                         savedInstanceState: Bundle?): View? {
}

创建绑定对象

现在,fragment 将无法编译。为使 Fragment 能够编译,您需要创建绑定对象并膨胀 Fragment 的视图(相当于为 Activity 使用 setContentView())。

  1. TitleFragment.ktonCreateView() 方法中,创建一个 binding 变量 (val binding)。
  2. 如需膨胀 fragment 的视图,请对 fragment 的 DataBindingUtil.inflate() 对象 Binding 对象调用 FragmentTitleBinding

    将四个参数传递到该方法中:
  • inflater,用于膨胀绑定布局的 LayoutInflater
  • 要膨胀的布局的 XML 布局资源。请使用已为您预先定义的布局之一 R.layout.fragment_title
  • 用于父级 ViewGroupcontainer。(此参数是可选的。)
  • false,适用于 attachToParent 值。
  1. DataBindingUtil.inflate 返回的绑定分配给 binding 变量。
  2. 从包含膨胀视图的方法中返回 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
   }

第 2 步:将新的 fragment 添加到主布局文件

在此步骤中,您需要将 TitleFragment 添加到应用的 activity_main.xml 布局文件中。

  1. 打开 res > layout > activity_main.xml,然后点击 Text 标签页以查看布局 XML 代码。
  2. 在现有 LinearLayout 元素内,添加 fragment 元素。
  3. 将 fragment 的 ID 设置为 titleFragment
  4. 将 fragment 的名称设为 fragment 类的完整路径(在本例中为 com.example.android.navigation.TitleFragment)。
  5. 将布局宽度和高度设置为 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>
  1. 运行应用。fragment 已添加到主屏幕。

Android Studio 项目:AndroidTriviaFragment

在此 Codelab 中,您已向 AndroidTrivia 应用添加了一个 Fragment,在本课接下来的两个 Codelab 中,您将继续使用该 Fragment。

  • 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 的布局文件中的位置。

开始学习下一课:3.2 定义导航路径

如需本课程中其他 Codelab 的链接,请参阅“Android Kotlin 基础知识”Codelab 着陆页