一个 片段 表示活动中用户界面的模块化部分。片段具有自己的生命周期,接收自己的输入事件,并且您可以在包含活动运行时添加或删除片段。
本文档介绍如何创建片段并将其包含在活动中。
设置您的环境
片段需要依赖于 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.3" // Java language implementation implementation "androidx.fragment:fragment:$fragment_version" // Kotlin implementation "androidx.fragment:fragment-ktx:$fragment_version" }
Kotlin
dependencies { val fragment_version = "1.8.3" // 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。FragmentActivity
是 AppCompatActivity
的基类,因此,如果您已经正在子类化 AppCompatActivity
以在您的应用中提供向后兼容性,则无需更改活动基类。
您可以通过在 Activity 的布局文件中定义 Fragment,或者通过在 Activity 的布局文件中定义一个 Fragment 容器并在 Activity 内部以编程方式添加 Fragment 来将您的 Fragment 添加到 Activity 的视图层次结构中。无论哪种情况,您都需要添加一个 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 将被实例化,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
。然后,您可以使用 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 事务。这是为了确保仅在首次创建 Activity 时才添加 Fragment。当发生配置更改并重新创建 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 事务和 FragmentManager
在 Fragment 管理器指南 中有更详细的介绍。