0.概述

是什么?
Fragment是应用界面中可以重复使用的一部分,可以定义自己的布局、管理自己的生命周期以及处理自己的输入事件。

如何存在?
Fragment不能独立存在,必须由Activity或者另一个Fragment托管

特点?
模块化:

  • Fragment将界面分成离散的模块,不同的Fragment管理自己负责的模块。
  • 当页面比较大或者小的时候,Activity管理整个界面比较麻烦,可以引入Fragment管理界面布局。
  • Activity负责管理界面导航,而Fragment用于管理界面UI展示列表等界面元素
  • 图示
    同一屏幕的采用不同屏幕尺寸的两个版本。在左侧,大屏幕包含一个由 Activity 控制的抽屉式导航栏和一个由 Fragment 控制的网格列表。在右侧,小屏幕包含一个由 Activity 控制的底部导航栏和一个由 Fragment 控制的线性列表。

1.Fragment的创建

1.1创建Fragment类

例:

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

1.2将Fragment添加到Activity中

1.2.1 通过xml添加Fragment

将下面代码插入到Activity的xml文件中即可:

<!-- 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类名

1.2.2 动态添加

  • 将代码插入到Activity的xml中:
<!-- 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" />
  • 在Activity中添加对应代码
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();
        }
    }
}

注意: 代码中是在savedInstanceStat为null的时候添加,确保界面在首次创建界面的时候添加,当配置变化的时候,不需要重复添加,因为Fragment会从savedInstanceState中恢复。


如果需要传递数据,则实例代码如下:

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)
                //将bundle作为参数传过去
                .add(R.id.fragment_container_view, ExampleFragment.class, bundle)
                .commit();
        }
    }
}

Fragment中接收:

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");
        ...
    }
}

2.Fragment管理器

  • FragmentManager类用于负责管理Fragment,比如添加、移除、替换操作以及将操作添加到返回堆栈。

2.1调用FragmentManager

  • Activity调用
    通过 getSupportFragmentManager() 方法调用
  • Fragment调用
    在Fragment中,可以嵌套一个或者多个子Fragment,因此在Fragment中可以通过getChildFragmentManager() 获取子FragmentManager的引用。如果需要访问父FragmentManager,可以通过 getParentFragmentManager() 调用。

2.2 使用FragmentManager

  • 调用FragmentManager.popBackStack()来将最上面的fragment从堆栈中弹出
  • 调用 addToBackStack()来添加多个Fragment、替换多个容器中的Fragment。

2.3 执行事务

  • 如果需要再布局中显示Fragment,需要用FragmentManager创建 FragmentTransaction ,然后就可以执行add()和replace()操作。
    例:
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    .replace(R.id.fragment_container, ExampleFragment.class, null)
    .setReorderingAllowed(true)
    .addToBackStack("name") // name can be null
    .commit();
  • ExampleFragment 会替换当前在布局容器中的 fragment(如有),该布局容器由 R.id.fragment_container ID 进行标识。将 fragment 的类提供给 replace() 方法可让 FragmentManager 使用其 FragmentFactory 处理实例化。
  • setReorderingAllowed(true) 可优化事务中涉及的 fragment 的状态变化,以使动画和过渡正常运行。
  • 调用 addToBackStack() 会将事务提交到返回堆栈。用户稍后可以通过按“返回”按钮反转事务,并恢复上一个 fragment。如果您在一个事务中添加或移除了多个 fragment,弹出返回堆栈时,所有这些操作都会撤消。在 addToBackStack() 调用中提供的可选名称使您能够使用 popBackStack() 弹回到该特定事务。
  • 如果您在执行移除 fragment 的事务时未调用 addToBackStack(),则提交事务时会销毁已移除的 fragment,用户无法返回到该 fragment。如果您在移除某个 fragment 时调用了 addToBackStack(),则该 fragment 只会 STOPPED,稍后当用户返回时它会 RESUMED。在这种情况下,其视图会被销毁。

2.3.1查找Fragment

  • 通过findFragmentById()获取对布局容器当前Fragment引用。实例:
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    .replace(R.id.fragment_container, ExampleFragment.class, null)
    .setReorderingAllowed(true)
    .addToBackStack(null)
    .commit();

...

ExampleFragment fragment =
        (ExampleFragment) fragmentManager.findFragmentById(R.id.fragment_container);
  • 通过分配唯一标识,通过 findFragmentByTag()获取引用
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    .replace(R.id.fragment_container, ExampleFragment.class, null, "tag")
    .setReorderingAllowed(true)
    .addToBackStack(null)
    .commit();

...

ExampleFragment fragment = (ExampleFragment) fragmentManager.findFragmentByTag("tag");

2.4支持多个返回堆栈

  • 有的时候,应用可能需要支持多个返回堆栈,比如底部使用导航栏。FragmentManager通过saveBackStack()和restoreBackStack()方法支持多个返回堆栈。

假设,使用addToBackStack()提交了FragmentTransaction,从而将Fragment返回到堆栈:

supportFragmentManager.beginTransaction()
  .replace(R.id.fragment_container, ExampleFragment.class, null)
  // setReorderingAllowed(true) and the optional string argument for
  // addToBackStack() are both required if you want to use saveBackStack().
  .setReorderingAllowed(true)
  .addToBackStack("replacement")
  .commit();
  • 可以用saveBackStack()来保存此Fragment事务和ExampleFragment的状态:
supportFragmentManager.saveBackStack("replacement");
  • 可以使用restoreBackStack()来恢复所有弹出事务以及所保存的Fragment状态:
supportFragmentManager.restoreBackStack("replacement");

3.Fragment事务

是什么?

  • 用户每一次提交Fragment就叫做一个事务,并且可以使用FragmentTransaction类提供的API来指定在事务中做什么。
  • 可以通过beginTransaction()函数从FragmentManager中获取FragmentTransaction的实例
    例:
FragmentManager fragmentManager = ...
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
  • 每一个FragmentTransaction最后的调用必须是提交事务。commit()方法调用向FragmentManager发出信号,表示所有的操作都被添加到了事务里。
FragmentManager fragmentManager = ...
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

// 在这里可以添加操作

fragmentTransaction.commit();
  • 每一个FragmentTransaction都应该使用.setReorderingAllowed(true)。
FragmentManager fragmentManager = ...
fragmentManager.beginTransaction()
    ...
    .setReorderingAllowed(true)
    .commit();

3.1添加或者移除Fragment

  • 添加:add()
  • 删除:remove()
  • 取代:replace()
// 创建FRagment和事务
FragmentManager fragmentManager = ...
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setReorderingAllowed(true);

// Replace whatever is in the fragment_container view with this fragment
transaction.replace(R.id.fragment_container, ExampleFragment.class, null);

// 提交事务
transaction.commit();

4.Fragment生命周期

Android开发 FirebaseManager在哪 安卓开发 fragment_android