Android官方文档学习笔记
创建Fragment
甲Fragment表示用户界面的活动内的模块化部分。Fragment有自己的生命周期,接收自己的输入事件,您可以在包含活动的运行时添加或删除Fragment。
本文档介绍了如何创建Fragment并将其包含在活动中。
设置您的环境
片段需要依赖于 AndroidX 片段库。您需要将Google Maven 存储库添加 到您的项目build.gradle文件中以包含此依赖项。
buildscript {
...
repositories {
google()
...
}
}
allprojects {
repositories {
google()
...
}
}
要将 AndroidX Fragment 库包含到您的项目中,请在您的应用程序build.gradle文件中添加以下依赖项:
dependencies {
def fragment_version = "1.3.6"
// Java language implementation
implementation "androidx.fragment:fragment:$fragment_version"
// Kotlin
implementation "androidx.fragment:fragment-ktx:$fragment_version"
}
创建片段类
要创建片段,请扩展 AndroidX Fragment类,并覆盖其方法以插入您的应用程序逻辑,类似于创建Activity类的方式。要创建定义自己布局的最小片段,请将片段的布局资源提供给基本构造函数,如以下示例所示:
class ExampleFragment : Fragment(R.layout.example_fragment)
Fragment 库还提供了更专业的片段基类:
- DialogFragment
显示浮动对话框。使用此类创建对话框是在Activity类中使用对话框辅助方法的一个很好的替代方法 ,因为片段会自动处理Dialog. - PreferenceFragmentCompat
将Preference对象层次结构显示 为列表。您可以使用PreferenceFragmentCompat来 创建设置屏幕为您的应用程序。
将片段添加到活动
通常,您的片段必须嵌入到 AndroidX FragmentActivity中才能为该活动的布局贡献一部分 UI。FragmentActivity 是 的基类 AppCompatActivity,因此如果您已经子类化AppCompatActivity以在您的应用程序中提供向后兼容性,那么您不需要更改您的活动基类。
您可以通过在活动的布局文件中定义片段或在活动的布局文件中定义片段容器,然后以编程方式从活动中添加片段,将片段添加到活动的视图层次结构中。在任何一种情况下,您都需要添加一个 FragmentContainerView 定义片段应放置在活动视图层次结构中的位置。强烈建议始终使用 a 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 创建 a 以将片段添加到FragmentManager.
注意:您可以使用class属性而不是android:name作为指定Fragment实例化哪个的替代方法。
以编程方式添加片段
要将片段以编程方式添加到您的 Activity 布局中,布局应包含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 方法不同,此处android:name不使用该属性 FragmentContainerView,因此不会自动实例化特定片段。相反, a FragmentTransaction 用于实例化片段并将其添加到活动的布局中。
当您的活动正在运行时,您可以进行片段事务,例如添加、删除或替换片段。在您的 中FragmentActivity,您可以获得 的实例,该实例 FragmentManager可用于创建FragmentTransaction. 然后,您可以onCreate()使用FragmentTransaction.add(),在您的活动的方法中 实例化您的片段,ViewGroup在您的布局中传递容器的ID 和您要添加的片段类,然后提交事务,如以下示例所示:
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();
}
}
}
注意:你应该总是用setReorderingAllowed(true)进行时FragmentTransaction。
在前面的例子中,注意时才创建片段交易savedInstanceState是null。这是为了确保在首次创建活动时仅添加一次片段。当发生配置更改并重新创建活动时, savedInstanceState不再是null,并且不需要第二次添加片段,因为片段会自动从savedInstanceState.
如果您的片段需要一些初始数据,则可以通过Bundle在对 的调用中提供 a 来将参数传递给您的片段FragmentTransaction.add(),如下所示:
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();
}
}
}
Bundle然后可以通过调用从片段中检索 参数requireArguments(),并且Bundle可以使用适当的getter 方法来检索每个参数。
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");
...
}
}