在Android中执行Backstack片段问题的生命周期方法

时间:2019-01-24 11:36:21

标签: android android-fragments android-lifecycle

我有一个包含两个片段的活动,并且希望使用后退按钮从第二个片段返回时执行第一个片段。我在将第一个片段导航到第二个片段时正在使用add()。这是我的场景和代码片段:

第一个片段

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {

        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.one_fragment, container, false);    

        final Button button = (Button) view.findViewById(R.id.buttonChange);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                buttonClicked(v);
            }
        });

        return view;
    }

    public void buttonClicked(View view) {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.fragment_Container, new TwoFragment());
        fragmentTransaction.addToBackStack("sdfsf");
        fragmentTransaction.commit();

}

移动到第二个片段,下面是代码:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.two_fragment, container, false);
        return view;
}

问题是,当我从第一个片段导航到第二个片段,然后使用返回按钮在第一个片段中再次返回时,第一个片段生命周期方法未执行。如果我使用add()而不是使用replace(),那么生命周期方法将正确执行。我知道add()replace()之间的区别,但是我想使用add(),并且当我使用“后退”按钮返回第一个片段时,我还想使用导航回调来处理一些逻辑。 / p>

还尝试了以下代码:

fragmentManager.addOnBackStackChangedListener(
        new FragmentManager.OnBackStackChangedListener() {
                public void onBackStackChanged() {
                        Log.e(TAG, "onBackStackChanged: ");
                        // Update your UI here.
                }
});

但是它还会多次调用并产生异常。

我该如何处理?当我从第二个片段返回时,特别要处理第一个片段中的一些逻辑。

2 个答案:

答案 0 :(得分:1)

我想到的最简单的方法是在完成第二个片段后设置结果,该片段实际上是通过onActivityResult方法告诉第一个片段“恢复”。

创建片段B的实例时,调用#setTargetFragment()并传入片段A作为目标片段。然后,当片段B完成并要返回片段A时,在退出之前,您可以通过调用以下命令为片段A设置结果:

getTargetFragment().onActivityResult(getTargetRequestCode(), RESULT_FRAGMENT_B_FINISHED,null)
///// horizontal scroll padding

请注意, RESULT_FRAGMENT_B_FINISHED 是您在某处定义的一些静态整数,例如

public static final int RESULT_FRAGMENT_B_FINISHED = 123123;

现在在Fragment A中,您需要做的就是重写onActivityResult并检查请求代码是否与setTargetFragment中的请求代码整数匹配,并且结果代码也与RESULT_FRAGMENT_B_FINISHED匹配,如果可以的话,您可以运行应从onResume触发的代码()。

#getTargetFragment()

#onActivityResult()

#getTargetRequestCode()

答案 1 :(得分:0)

我建议您使用SharedViewModel,而不是在两个片段之间传递数据。

这个想法是,第一个片段观察一些数据以进行更改,而第二个片段编辑该数据。

示例:

共享的ViewModel

public class SharedViewModel extends ViewModel {

  private final MutableLiveData<Item> selected = new 
  MutableLiveData<Item>();

  public void select(Item item) {
      selected.setValue(item);
  }

  public LiveData<Item> getSelected() {
      return selected;
  }
}

第一个片段

public class FirstFragment extends Fragment {

  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      SharedViewModel model = 
      ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
      model.getSelected().observe(this, { item ->
         // Update the UI.
      });
  }
}

第二个片段

public class SecondFragment extends Fragment {

  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      SharedViewModel model = 
      ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
      model.select(new Item("value 1","value 2");
  }
}

您可以从此处开始了解有关ViewModels,LiveData和体系结构组件的信息:https://developer.android.com/topic/libraries/architecture/viewmodel#java

此答案假设您要基于某些数据更改执行某些逻辑。如果不是这种情况,您可以解释一下要执行哪种逻辑,我将编辑答案。