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.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") }
创建 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 的布局。FragmentActivity
是 AppCompatActivity
的基类,因此,如果您已在应用中通过对 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(); } } }
请注意,在上面的示例中,只有在 savedInstanceState
为 null
时,才会创建 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
。