我有一个包含两个片段的活动,并且希望使用后退按钮从第二个片段返回时执行第一个片段。我在将第一个片段导航到第二个片段时正在使用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.
}
});
但是它还会多次调用并产生异常。
我该如何处理?当我从第二个片段返回时,特别要处理第一个片段中的一些逻辑。
答案 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触发的代码()。
答案 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
此答案假设您要基于某些数据更改执行某些逻辑。如果不是这种情况,您可以解释一下要执行哪种逻辑,我将编辑答案。