android - 对 Android Fragment Transaction 感到疯狂

标签 android fragment tabbar fragmenttransaction

我无法理解我的 fragment 交易的这种行为。在我发疯之前有人可以介入吗?在我的 MainActivity 中,我正确设置了它:

    private final GuideFragment guideFragment = new GuideFragment();
    private final MapFragment mapFragment = new MapFragment();
    private final MoreFragment moreFragment = new MoreFragment();

    Fragment active;

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
                = new BottomNavigationView.OnNavigationItemSelectedListener() {

            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                FragmentTransaction transaction = getFragmentManager().beginTransaction();
                switch (item.getItemId()) {
                    case R.id.navigation_guide:
                        if (!guideFragment.isAdded()) {
                            transaction.add(R.id.content,guideFragment).commit();
                            active = guideFragment;
                            Log.d(TAG, "add Fragment1");
                            break;
                        } else {
                            transaction.hide(active).show(guideFragment).commit();
                            active = guideFragment;
                            Log.d(TAG, "show Fragment1");
                            break;
                        }
                    case R.id.navigation_map:
                        if (!mapFragment.isAdded()) {
                            transaction.add(R.id.content, mapFragment).commit();
                            active = mapFragment;
                            Log.d(TAG,"add Fragment2");
                            break;
                        } else {
                            transaction.hide(active).show(mapFragment).commit();
                            active = mapFragment;
                            Log.d(TAG,"show Fragment2");
                            break;
                        }
                    case R.id.navigation_more:
                        if (!moreFragment.isAdded()) {
                            transaction.add(R.id.content,moreFragment).commit();
                            active = moreFragment;
                            Log.d(TAG,"add Fragment3");
                            break;
                        } else {
                            transaction.hide(active).show(moreFragment).commit();
                            active = moreFragment;
                            Log.d(TAG,"show Fragment3");
                            break;
                        }
                }

                return true;
            }

        };

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);

        //start with guide view/fragment
        switchTabView(R.id.navigation_guide);

    }

    //method to start or switch a tab
    private void switchTabView(int itemId) {
        navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
        navigation.setSelectedItemId(itemId);

    }

我的应用程序有 3 个选项卡,如上所示:Tab1(指南)Tab2( map )Tab3(更多)。

当应用程序启动时,第一个选项卡(指南)将被添加并正确显示。 然后我点击 map (下一个 fragment ),这将被添加并正确显示。 最后,在“更多”选项卡(我的第三个选项卡)上一切都很好。

但是当 Activity 启动时,我点击 1-3( map 指南)到目前为止是正确的 - 然后 3-2(更多选项卡到 map 选项卡)一切都很好 - 但是然后从 2-1( map 到指南)返回,突然出现了第三个选项卡 fragment (更多),其中应该显示指南 fragment 。

有人知道出了什么问题吗? 希望得到一些帮助。

感谢 Mateus 的解决方案

transaction.hide(fragment3).hide(fragment2).show(fragment1).commit();

我不确定调用两次隐藏 fragment 是否那么干净,但我认为使用 3 个选项卡仍然可以。对于更多选项卡,我会考虑以不同的方式处理这个问题,例如remove()或replace() fragment 。

更新 - 解决方案如预期更加棘手:

           switch (item.getItemId()) {
                case R.id.navigation_guide:
                    if (!guideFragment.isAdded()) {
                        transaction.add(R.id.content,guideFragment).commit();
                        Log.d(TAG, "add Fragment1");
                        break;
                    } else {
                        if (!moreFragment.isAdded() && mapFragment.isAdded()) {
                            transaction.hide(mapFragment).show(guideFragment).commit();
                        }
                        if (moreFragment.isAdded() && !mapFragment.isAdded()) {
                            transaction.hide(moreFragment).show(guideFragment).commit();
                        }
                        if (moreFragment.isAdded() && mapFragment.isAdded()) {
                            transaction.hide(moreFragment).hide(mapFragment).show(guideFragment).commit();
                        }

                        Log.d(TAG, "show Fragment1");
                        break;
                    }
                case R.id.navigation_map:
                    if (!mapFragment.isAdded()) {
                        transaction.add(R.id.content, mapFragment).commit();
                        Log.d(TAG,"add Fragment2");
                        break;
                    } else {
                        if (!moreFragment.isAdded()) {
                            transaction.hide(guideFragment).show(mapFragment).commit();
                        } else {
                            transaction.hide(guideFragment).hide(moreFragment).show(mapFragment).commit();
                        }
                        Log.d(TAG,"show Fragment2");
                        break;
                    }
                case R.id.navigation_more:
                    if (!moreFragment.isAdded()) {
                        transaction.add(R.id.content,moreFragment).commit();
                        Log.d(TAG,"add Fragment3");
                        break;
                    } else {
                        if (!mapFragment.isAdded()) {
                            transaction.hide(guideFragment).show(moreFragment).commit();
                        } else {
                            transaction.hide(guideFragment).hide(mapFragment).show(moreFragment).commit();
                        }
                        Log.d(TAG,"show Fragment3");
                        break;
                    }
            }

终于没有bug了,你必须检查是否添加了其他 fragment !

最佳答案

当你从 2 返回到 1 时,这一行将被调用:

transaction.hide(active).show(guideFragment).commit();

问题是,当您隐藏 Activity ( fragment 2)并显示 fragment 1 时, fragment 3(在 fragment 1 之后添加,因此位于 fragment 1 的“顶部”)仍然显示。您还必须对 fragment 3 调用 hide 才能看到 fragment 1。

换句话说,每次您想要显示特定 fragment 时,您都需要调整代码以隐藏所有其他 fragment 。

另请检查this discussion关于在显示/隐藏和添加/删除/替换之间进行选择,以确认第一个策略更适合您的需求。

关于android - 对 Android Fragment Transaction 感到疯狂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44445227/

相关文章:

android - 我的 cordova 应用程序在检测到 NFC 标签后无法启动

Android: fragment 和返回堆栈

android - 如何在 ButtomSheetDialogFragment Android 中设置左右边距?

Flutter - 如何在 TabBarView 的主体内导航?

ios - 以编程方式快速更改标签栏项目图像

ios - 如何知道点击了哪个 Tabbar 菜单

android - Jetpack Compose 自定义 UI - 带动画的速度计

Android Firebase getChildrenCount() 不算数

android - Eclipse - Android 可绘制图像资源不刷新

android - 可见时刷新 fragment 中的适配器