安卓Fragment按钮绑定事件混乱问题
问题描述
我在安卓开发中出现了按钮绑定事件混乱的问题。页面结构是:
MainActivity:
tab1:
Fragment1(包含一个ConfigEditFragment)
tab2:
Fragment2(包含一个ConfigEditFragment)
每个 ConfigEditFragment 都有一个刷新按钮,点击后调用从父级元素传过来的回调函数。现在的问题是无论我点击的是 Fragment1 的刷新按钮还是 Fragment2 的刷新按钮,触发的都是 test2()。而这两个 Fragment 里包含的 ConfigEditFragment 也确实是不同的内容。请问这是什么原因?
public class Fragment1 extends Fragment {
private ConfigEditorFragment configFragment1 = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1_page, container, false);
Context context = requireContext();
FragmentTransaction ft = getParentFragmentManager().beginTransaction();
configFragment1 = ConfigEditorFragment.newInstance(new Data1(), this::test1);
ft.replace(R.id.fragment1_container, configFragment1, "config_fragment_1");
ft.commit();
return rootView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void test1() {
Toast.makeText(requireContext(), "Fragment1 test1 called", Toast.LENGTH_SHORT).show();
}
public class Fragment2 extends Fragment {
private ConfigEditorFragment configFragment2 = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment2_page, container, false);
Context context = requireContext();
FragmentTransaction ft = getParentFragmentManager().beginTransaction();
configFragment2 = ConfigEditorFragment.newInstance(new Data2(), this::test2);
ft.replace(R.id.fragment2_container, configFragment2, "config_fragment_2");
ft.commit();
return rootView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void test2() {
Toast.makeText(requireContext(), "Fragment2 test2 called", Toast.LENGTH_SHORT).show();
}
public class MainPagerAdapter extends FragmentStateAdapter {
public MainPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return new SettingsFragment();
case 1:
return new Fragment1();
default:
return new Fragment2();
}
}
@Override
public int getItemCount() {
return 3;
}
}
原因
Fragment 管理层级 + FragmentManager 用错了,导致同一个 ConfigEditorFragment 实例被复用 / 覆盖问题,从而按钮事件指向了最后一次绑定的回调(Location 的)。
解决方案
将 getParentFragmentManager() 改为 getChildFragmentManager()。