创建 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.8.8"

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

Kotlin

dependencies {
    val fragment_version = "1.8.8"

    // 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 为您的应用创建设置屏幕

将 Fragment 添加到 Activity

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

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

通过 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 将被实例化,onInflate() 将在新实例化的 Fragment 上调用,并创建一个 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 方法不同,这里 FragmentContainerView 上未使用 android:name 属性,因此不会自动实例化任何特定 Fragment。取而代之的是,使用 FragmentTransaction 来实例化 Fragment 并将其添加到 Activity 的布局中。

在 Activity 运行时,您可以执行 Fragment 事务,例如添加、移除或替换 Fragment。在您的 FragmentActivity 中,您可以获取 FragmentManager 的实例,该实例可用于创建 FragmentTransaction。然后,您可以在 Activity 的 onCreate() 方法中,使用 FragmentTransaction.add() 实例化您的 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();
        }
    }
}

在前面的示例中,请注意 Fragment 事务仅在 savedInstanceStatenull 时才创建。这是为了确保 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 事务和 FragmentManagerFragment 管理器指南中有更详细的介绍。