使用BottomNavigationView在片段之间导航

时间:2020-04-16 16:41:20

标签: android android-fragments

有一个NavigationView打开一个片段,在该片段中有一个BottomNavigationView。底部导航视图应在两个片段之间切换。

注意:应用程序启动时,它将打开第一个空白片段(称为Home),因此,当我单击第二个菜单项时,它将打开另一个片段(其中包含底部导航)。

我试图通过FragmentTransaction从一个片段切换到另一个片段:

public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
            fragmentManager.popBackStack();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            final Fragment fragment;
            if (item.getItemId() == R.id.menu_alert) {
                fragment = new IPAlertFragment();
            } else {
                fragment = new IPStatsFragment();
            }
            fragmentTransaction.replace(R.id.nav_host_fragment, fragment).commit();
            return false;
        }
    };
    BottomNavigationView navigation = (BottomNavigationView) getActivity().findViewById(R.id.bottom_navigation);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}

当我第一次从导航菜单中打开片段时,它工作正常,但是当我再次在导航菜单上单击时,BottomNavigationView.onNavigationItemSelectedListener不再触发并且无法切换彼此的碎片。

因此,我尝试使用NavController来实现自己的目标,如下所示:

public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            final NavController navController = NavHostFragment.findNavController(NavFragment.this);
            if (item.getItemId() == R.id.menu_alert) {
                navController.navigate(R.id.action_openAlert);
            } else {
                navController.navigate(R.id.action_openStats);
            }
            return false;
        }
    };
    BottomNavigationView navigation = (BottomNavigationView) getActivity().findViewById(R.id.bottom_navigation);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}

但是当我导航到另一个片段时,左侧菜单栏将图标更改为“后退箭头”,这是一种新活动,我必须使用“后退”按钮(或菜单后退图标)才能显示前一个标签。

我想像侧边菜单一样导航到覆盖当前“屏幕”的目标片段。

这里是mobile_navigation.xml

<fragment
    android:id="@+id/nav_ip_alert"
    android:name="IPAlertFragment"
    android:label="@string/menu_ip"
    tools:layout="@layout/fragment_i_p_alert">
    <action
        android:id="@+id/action_openStats"
        app:destination="@id/nav_ip_stats"
        app:launchSingleTop="false" />
</fragment>

<fragment
    android:id="@+id/nav_ip_stats"
    android:name="IPStatsFragment"
    android:label="@string/menu_ip"
    tools:layout="@layout/stats_tabs">
    <action
        android:id="@+id/action_openAlert"
        app:destination="@id/nav_ip_alert"
        app:launchSingleTop="false" />
</fragment>

我不知道出了什么问题(尤其是第一个解决方案),有什么想法吗? 谢谢。

1 个答案:

答案 0 :(得分:0)

最后我解决了我的问题:

当我第一次从导航菜单中打开片段时,它工作正常,但是当我再次在导航菜单上单击时,BottomNavigationView.onNavigationItemSelectedListener不再触发,并且我无法从片段中切换到另一个。

该问题是由导航菜单引起的,未调用侦听器,因为我在活动中使用了

NavigationUI.setupWithNavController(navigationView, navController);

这会覆盖我的OnNavigationItemSelectedListener,因此我删除了该行,并将侦听器设置为以下内容:

final NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new 
NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            FragmentManager fm = getSupportFragmentManager();
            fm.popBackStackImmediate();
            boolean handled = NavigationUI.onNavDestinationSelected(item, navController);
            if (handled) {
                ViewParent parent = navigationView.getParent();
                if (parent instanceof DrawerLayout) {
                    ((DrawerLayout) parent).closeDrawer(navigationView);
                }
            }
            return handled;
        }
    });

这是一个覆盖我的侦听器的NavigationUI:

public static void setupWithNavController(@NonNull final NavigationView navigationView,
        @NonNull final NavController navController) {
    navigationView.setNavigationItemSelectedListener(
            new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    boolean handled = onNavDestinationSelected(item, navController);
                    //******* CUTTED ***************
                    return handled;
                }
            });
}

因此,代替setupWithNavController,我可以正确浏览选项卡。