创建 Fragment

您可以将 Fragment 视为 Activity 的模块化部分,有自己的生命周期,接收自己的输入事件,并且可以在 Activity 运行期间添加或移除(有点像可以在不同 Activity 中重用的“子 Activity”)。本节课介绍如何使用支持库扩展 Fragment 类,以便您的应用与运行低至 Android 1.6 的系统版本的设备保持兼容。

您应该创建一个生命周期感知组件,而不是在 Fragment 的生命周期方法中设置依赖组件。生命周期感知组件可以处理 Fragment 历经整个生命周期时所需的任何设置或拆解工作。该组件随后可以在其他 Fragment 和 Activity 中重复使用以避免代码重复,并减少您在 Fragment/Activity 本身中需要执行的设置量。有关详情,请参阅使用生命周期感知组件处理生命周期

在开始本节课之前,您必须设置 Android 项目以使用支持库。如果您以前没有使用过支持库,请按照支持库设置文档设置项目以使用 v4 库。不过,您也可以通过使用 v7 appcompat 库在 Activity 中加入应用栏,该库与 Android 2.1(API 级别 7)兼容,并且还包含 Fragment API。

如需详细了解如何实现 Fragment,请参阅 Fragment。您还可以通过浏览相关示例应用了解详情。

创建 Fragment 类

要创建 Fragment,请扩展 Fragment 类,然后替换关键生命周期方法以插入应用逻辑,创建方式类似于 Activity 类。

创建 Fragment 时的一个区别是您必须使用 onCreateView() 回调定义布局。事实上,这是为了让 Fragment 运行所需的唯一回调。例如,下面是一个指定其自身布局的简单 Fragment:

Kotlin

    import android.os.Bundle
    import android.support.v4.app.Fragment
    import android.view.LayoutInflater
    import android.view.ViewGroup

    class ArticleFragment : Fragment() {
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup,
                         savedInstanceState: Bundle?): View {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.article_view, container, false)
        }
    }
    

Java

    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.ViewGroup;

    public class ArticleFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.article_view, container, false);
        }
    }
    

和 Activity 一样,Fragment 也应实现其他生命周期回调,以便您能在为 Activity 添加或移除 Fragment 以及 Activity 在其生命周期状态之间转换时管理 Fragment 的状态。例如,在调用 Activity 的 onPause() 方法时,Activity 中的任何 Fragment 也会收到对 onPause() 的调用。

有关 Fragment 生命周期和回调方法的详情,请参阅 Fragment 开发者指南。

使用 XML 向 Activity 添加 Fragment

虽然 Fragment 是可重复使用的模块化界面组件,但 Fragment 类的每个实例都必须与父级 FragmentActivity 相关联。您可以通过在 Activity 布局 XML 文件中定义每个 Fragment 来实现这种关联。

注意FragmentActivity 是支持库中提供的特殊 Activity,用于处理早于 API 级别 11 的系统版本上的 Fragment。如果您支持的最低系统版本为 API 级别 11 或更高版本,那么您可以使用常规 Activity

下面是一个示例布局文件,该文件在设备屏幕被视为“大”(由目录名称中的 large 限定符指定)时向 Activity 添加两个 Fragment。

res/layout-large/news_articles.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <fragment android:name="com.example.android.fragments.HeadlinesFragment"
                  android:id="@+id/headlines_fragment"
                  android:layout_weight="1"
                  android:layout_width="0dp"
                  android:layout_height="match_parent" />

        <fragment android:name="com.example.android.fragments.ArticleFragment"
                  android:id="@+id/article_fragment"
                  android:layout_weight="2"
                  android:layout_width="0dp"
                  android:layout_height="match_parent" />

    </LinearLayout>
    

提示:有关针对不同屏幕尺寸创建布局的详细信息,请参阅支持不同的屏幕尺寸

然后将布局应用到您的 Activity:

Kotlin

    import android.os.Bundle
    import android.support.v4.app.FragmentActivity

    class MainActivity : FragmentActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.news_articles)
        }
    }
    

Java

    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;

    public class MainActivity extends FragmentActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.news_articles);
        }
    }
    

如果您使用的是 v7 appcompat 库,则 Activity 应扩展 AppCompatActivity,它是 FragmentActivity 的子类。有关详情,请阅读添加应用栏

注意:如果您通过在布局 XML 文件中定义 Fragment,将该 Fragment 添加到 Activity 布局中,您不能在运行时移除该 Fragment。如果您计划在用户互动期间更换 Fragment,则必须在 Activity 首次启动时就向其添加 Fragment,如构建灵活的界面中所示。