【问题标题】:Fragment BackStack lifecycle issuesFragment BackStack 生命周期问题
【发布时间】:2019-10-11 20:58:48
【问题描述】:

我有一个片段活动,它有一个片段A。片段A在onViewCreated方法中做了一些重要的事情:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mission1 = view.findViewById(R.id.mission1);
    mission2 = view.findViewById(R.id.mission2);
    mission3a = view.findViewById(R.id.mission3a);
    mission3b = view.findViewById(R.id.mission3b);

    imageButtonList.add(mission1);
    imageButtonList.add(mission2);
    imageButtonList.add(mission3a);
    imageButtonList.add(mission3b);
    prepareButtons();
}

好的,现在,这个片段 A 有一个创建新片段 B 的按钮,但是我想在新的片段 B 中添加一个“返回”按钮,所以我在启动片段 B 时将片段 A 添加到 backstack 中:

FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
CampaignMissionFragment fragment = CampaignMissionFragment.newInstance(auxMission);
ft.replace(R.id.fragmentContainer, fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();

在片段 B 中,我将其添加到后退按钮 onClick():

getFragmentManager().popBackStack();

问题是,当我按回片段 B 时,片段 A 的 onViewCreated 方法被调用,因此我的 imageButtonList 数组内部的按钮数量错误,因为再次插入了相同的按钮。

解决此问题的正确方法是什么?我认为 Fragment 具有与活动类似的行为,您可以在其中将不想执行两次的代码放在 onCreate 中解决此问题。但在这种情况下,我不能这样做,因为我的视图在片段的 onCreate 方法中不可用。

【问题讨论】:

    标签: android android-fragments android-fragmentactivity fragment-backstack fragment-lifecycle


    【解决方案1】:

    您可以尝试清除 onDestroyView 中的 imageButtonList, 另一种解决方案是检查 savedInstanceState 是否不为空,如果是这种情况,请避免将按钮添加到列表中 还有,onCreate()中没有View相关的操作

    【讨论】:

      【解决方案2】:

      将片段活动的 onBackPressed 更新为 -

       @Override
          public void onBackPressed() {
              FragmentManager fm = getFragmentManager();
              if (fm.getBackStackEntryCount() > 0) {
                  fm.popBackStack();
              } else {
                  super.onBackPressed();
              }
          }
      

      【讨论】:

        【解决方案3】:

        检查 savedInstanceState 对象以确定这是否是第一次初始化 Fragment 并且仅在第一次通过时保存您的字段:

        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            mission1 = view.findViewById(R.id.mission1);
            mission2 = view.findViewById(R.id.mission2);
            mission3a = view.findViewById(R.id.mission3a);
            mission3b = view.findViewById(R.id.mission3b);
        
            if (savedInstanceState == null) {
                imageButtonList.add(mission1);
                imageButtonList.add(mission2);
                imageButtonList.add(mission3a);
                imageButtonList.add(mission3b);
                prepareButtons();
            }
        }
        

        【讨论】:

          【解决方案4】:

          尝试在 OneResume 中编写代码

           @Override
          public void onResume() {
              mission1 = view.findViewById(R.id.mission1);
              mission2 = view.findViewById(R.id.mission2);
              mission3a = view.findViewById(R.id.mission3a);
              mission3b = view.findViewById(R.id.mission3b);
          
              imageButtonList.add(mission1);
              imageButtonList.add(mission2);
              imageButtonList.add(mission3a);
              imageButtonList.add(mission3b);
              prepareButtons();
          }
          

          【讨论】:

          • 这将导致imageButtonList 每次恢复片段时都会添加 4 个新按钮(基本上是在您离开另一个应用程序并返回时)。这将比 OP 现在看到的更糟糕。
          猜你喜欢
          • 2016-03-30
          • 2014-06-08
          • 1970-01-01
          • 2011-07-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多