创建 fragment

Fragment 表示 Activity 内界面的模块化部分。Fragment 有自己的生命周期,会接收自己的输入事件,并且您可以在所包含的 Activity 运行期间添加或移除 Fragment。

本文档介绍如何创建 Fragment 以及如何将其包含在 Activity 中。

设置您的环境

Fragment 需要一个依赖于 AndroidX Fragment 库的依赖项。您需要将 Google Maven 代码库添加到项目的 settings.gradle 文件中,才能添加此依赖项。

Groovy

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        ...
    }
}

Kotlin

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        ...
    }
}

如需向您的项目添加 AndroidX Fragment 库,请在应用的 build.gradle 文件中添加以下依赖项:

Groovy

dependencies {
    def fragment_version = "1.6.2"

    // Java language implementation
    implementation "androidx.fragment:fragment:$fragment_version"
    // Kotlin
    implementation "androidx.fragment:fragment-ktx:$fragment_version"
}

Kotlin

dependencies {
    val fragment_version = "1.6.2"

    // Java language implementation
    implementation("androidx.fragment:fragment:$fragment_version")
    // Kotlin
    implementation("androidx.fragment:fragment-ktx:$fragment_version")
}

创建 Fragment 类

如需创建 Fragment,请扩展 AndroidX Fragment 类,然后替换其方法以插入您的应用逻辑,创建方式类似于 Activity 类。如需创建可定义自身布局的最小 Fragment,请向基本构造函数提供 Fragment 的布局资源,如以下示例所示:

Kotlin

class ExampleFragment : Fragment(R.layout.example_fragment)

Java

class ExampleFragment extends Fragment {
    public ExampleFragment() {
        super(R.layout.example_fragment);
    }
}

Fragment 库还提供更专业的 Fragment 基类:

DialogFragment
显示浮动对话框。使用此类创建对话框可有效代替使用 Activity 类中的对话框辅助方法,因为 Fragment 会自动处理 Dialog 的创建和清理。 如需了解详情,请参阅使用 DialogFragment 显示对话框
PreferenceFragmentCompat
以列表形式显示 Preference 对象的层次结构。您可以使用 PreferenceFragmentCompat 为您的应用创建设置屏幕

向 Activity 添加 Fragment

通常,您的 Fragment 必须嵌入 AndroidX FragmentActivity 中,才能将部分界面提供给该 Activity 的布局。FragmentActivityAppCompatActivity 的基类,因此,如果您已在应用中通过对 AppCompatActivity 进行子类化以向后兼容,则您无需更改 Activity 基类。

您可以将 Fragment 添加到 Activity 的视图层次结构中,方法是在 Activity 的布局文件中定义 Fragment,或在 Activity 的布局文件中定义 Fragment 容器然后从您的 Activity 内以编程方式添加 Fragment。无论是哪种情况,您都需要添加一个 FragmentContainerView,以定义应该将 Fragment 放置在 Activity 的视图层次结构中的哪个位置。强烈建议始终将 FragmentContainerView 用作 Fragment 的容器,因为 FragmentContainerView 包含特定于 Fragment 的修复,其他视图组(如 FrameLayout)无法提供此类修复。

通过 XML 添加 Fragment

如需以声明方式将 Fragment 添加到 Activity 布局的 XML 中,请使用 FragmentContainerView 元素。

以下是包含单个 FragmentContainerView 的 Activity 布局示例:

<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.example.ExampleFragment" />

android:name 属性指定需实例化的 Fragment 的类名称。膨胀 Activity 的布局后,系统会实例化指定的 Fragment,在新实例化的 Fragment 上调用 onInflate(),并创建 FragmentTransaction 以将 Fragment 添加到 FragmentManager 中。

以编程方式添加 Fragment

如需以编程方式将 Fragment 添加到 Activity 布局,布局应包含 FragmentContainerView 作为 Fragment 容器,如以下示例所示:

<!-- res/layout/example_activity.xml -->
<androidx.fragment.app.FragmentContainerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

与 XML 方法不同,android:name 属性不在此处的 FragmentContainerView 上使用,因此不会自动实例化特定 Fragment。而是使用 FragmentTransaction 实例化 Fragment 并将其添加到 Activity 的布局。

当您的 Activity 正在运行时,您可以执行 Fragment 事务,如添加、移除或替换 Fragment。在 FragmentActivity 中,您可以获取 FragmentManager 的实例,该实例可用于创建 FragmentTransaction。然后,您可以使用 FragmentTransaction.add() 在 Activity 的 onCreate() 方法中实例化 Fragment,传入布局内容器的 ViewGroup ID 和想要添加的 Fragment 类,然后提交该事务,如以下示例所示:

Kotlin

class ExampleActivity : AppCompatActivity(R.layout.example_activity) {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (savedInstanceState == null) {
            supportFragmentManager.commit {
                setReorderingAllowed(true)
                add<ExampleFragment>(R.id.fragment_container_view)
            }
        }
    }
}

Java

public class ExampleActivity extends AppCompatActivity {
    public ExampleActivity() {
        super(R.layout.example_activity);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                .setReorderingAllowed(true)
                .add(R.id.fragment_container_view, ExampleFragment.class, null)
                .commit();
        }
    }
}

请注意,在上面的示例中,只有在 savedInstanceStatenull 时,才会创建 Fragment 事务。这是为了确保仅添加该 Fragment 一次,即在首次创建 Activity 时添加。当配置发生更改并且重新创建 Activity 时,savedInstanceState 不再为 null,并且不需要再次添加 Fragment,因为 Fragment 会自动从 savedInstanceState 恢复。

如果您的 Fragment 需要一些初始数据,您可以通过在 FragmentTransaction.add() 调用中提供 Bundle 将参数传递到 Fragment,如下所示:

Kotlin

class ExampleActivity : AppCompatActivity(R.layout.example_activity) {
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (savedInstanceState == null) {
            val bundle = bundleOf("some_int" to 0)
            supportFragmentManager.commit {
                setReorderingAllowed(true)
                add<ExampleFragment>(R.id.fragment_container_view, args = bundle)
            }
        }
    }
}

Java

public class ExampleActivity extends AppCompatActivity {
    public ExampleActivity() {
        super(R.layout.example_activity);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null) {
            Bundle bundle = new Bundle();
            bundle.putInt("some_int", 0);

            getSupportFragmentManager().beginTransaction()
                .setReorderingAllowed(true)
                .add(R.id.fragment_container_view, ExampleFragment.class, bundle)
                .commit();
        }
    }
}

然后,您可以通过调用 requireArguments() 从 Fragment 中检索参数 Bundle,并且可以使用适当的 Bundle getter 方法检索每个参数。

Kotlin

class ExampleFragment : Fragment(R.layout.example_fragment) {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val someInt = requireArguments().getInt("some_int")
        ...
    }
}

Java

class ExampleFragment extends Fragment {
    public ExampleFragment() {
        super(R.layout.example_fragment);
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        int someInt = requireArguments().getInt("some_int");
        ...
    }
}

另请参阅

Fragment 管理器指南中详细介绍了 Fragment 事务和 FragmentManager