创建片段

一个 片段 表示活动中用户界面的模块化部分。片段具有自己的生命周期,接收自己的输入事件,并且您可以在包含活动运行时添加或删除片段。

本文档介绍了如何创建片段并将其包含在活动中。

设置您的环境

片段需要依赖于 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.5"

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

Kotlin

dependencies {
    val fragment_version = "1.8.5"

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

创建片段类

要创建片段,请扩展 AndroidX Fragment 类,并覆盖其方法以插入您的应用逻辑,类似于创建 Activity 类的方式。要创建定义自己布局的最小片段,请将片段的布局资源提供给基本构造函数,如下例所示

Kotlin

class ExampleFragment : Fragment(R.layout.example_fragment)

Java

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

Fragment 库还提供更多专门的片段基类

DialogFragment
显示浮动对话框。使用此类创建对话框是使用 Activity 类中的对话框帮助器方法的良好替代方法,因为片段会自动处理 Dialog 的创建和清理。有关更多详细信息,请参阅 使用 DialogFragment 显示对话框
PreferenceFragmentCompat
Preference 对象的层次结构显示为列表。您可以使用 PreferenceFragmentCompat 为您的应用 创建设置屏幕

将片段添加到活动

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

您可以通过在活动的布局文件中定义片段或通过在活动的布局文件中定义片段容器,然后从活动内部以编程方式添加片段,将您的片段添加到活动的视图层次结构中。在这两种情况下,您都需要添加一个 FragmentContainerView,该容器定义片段应放置在活动视图层次结构中的位置。强烈建议始终使用 FragmentContainerView 作为片段的容器,因为 FragmentContainerView 包含特定于片段的修复程序,而其他视图组(如 FrameLayout)则不提供这些修复程序。

通过 XML 添加片段

要将片段声明性地添加到活动的布局的 XML 中,请使用 FragmentContainerView 元素。

这是一个包含单个 FragmentContainerView 的示例活动布局

<!-- 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 的类名。当活动的布局膨胀时,会实例化指定的片段,onInflate() 会在新实例化的片段上调用,并且会创建一个 FragmentTransaction 以将片段添加到 FragmentManager

以编程方式添加片段

要以编程方式将片段添加到活动的布局中,布局应包含一个 FragmentContainerView 作为片段容器,如下例所示

<!-- 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 属性,因此不会自动实例化任何特定片段。相反,FragmentTransaction 用于实例化片段并将其添加到活动的布局中。

在活动运行期间,您可以进行片段事务,例如添加、删除或替换片段。在您的 FragmentActivity 中,您可以获取 FragmentManager 的实例,该实例可用于创建 FragmentTransaction。然后,您可以使用 FragmentTransaction.add() 在活动的 onCreate() 方法中实例化您的片段,传入布局中容器的 ViewGroup ID 和您要添加的片段类,然后提交事务,如下例所示

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 时才会创建片段事务。这是为了确保仅在首次创建活动时才添加片段。当发生配置更改并重新创建活动时,savedInstanceState 将不再为 null,并且不需要再次添加片段,因为片段会自动从 savedInstanceState 中恢复。

如果您的片段需要一些初始数据,可以通过在调用 Bundle 时提供 FragmentTransaction.add() 中的 参数来传递给您的片段,如下所示

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() 从您的片段内部检索参数 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");
        ...
    }
}

另请参阅

片段管理器指南中更详细地介绍了片段事务和 FragmentManager