Android IllegalStateException:使用BottomNavigation时尚未附加片段

Android IllegalStateException:使用BottomNavigation时尚未附加片段,android,android-fragments,navigation-drawer,navigationview,Android,Android Fragments,Navigation Drawer,Navigationview,我使用的是来自的BottomNavigationDrawer/BottomSheetDialog,其中BottomNavigationDrawer在单个活动内的多个片段之间切换 然而,我意识到,当在不使用菜单的情况下交换片段时,即通过单击片段中的按钮,使用主活动中的函数触发FragmentTransaction的解决方案也会导致崩溃 public void resetNavDefault(){ if(fragment == null) { fragment

我使用的是来自的
BottomNavigationDrawer
/
BottomSheetDialog
,其中
BottomNavigationDrawer
在单个活动内的多个片段之间切换

然而,我意识到,当在不使用菜单的情况下交换片段时,即通过单击片段中的按钮,使用主活动中的函数触发
FragmentTransaction
的解决方案也会导致崩溃

public void resetNavDefault(){
        if(fragment == null) {
            fragment = new BottomNavigationDrawerFragment();
            navigationView = fragment.getNavigationView();
        } else navigationView = fragment.getNavigationView();
        //navigationView.getMenu().getItem(0).setChecked(true);
        Log.d(TAG, "resetNavDefault: setting check");
        MenuItem item = navigationView.getMenu().getItem(0);
        navigationView.getMenu().performIdentifierAction(item.getItemId(), 0);
    }
我意识到这是由于
getSupportFragmentManager
为null造成的,这不是正确的解决方案,因为我不使用嵌套片段,只在单个活动中使用多个片段

我还尝试在何处实施此解决方案

(由于
if(!isAdded())返回;
条件),但启动新片段的按钮没有响应(按钮不工作)

如何使用
FragmentTransaction
在两个片段之间导航,而不会导致NPE,也不会使菜单选择处于不一致的状态

我的
BottomNavigationDrawer
实现如下:

底部导航抽屉

public class BottomNavigationDrawerFragment extends BottomSheetDialogFragment {

    BottomNavigationDrawerFragment fragment;
    public NavigationView navigationView;
    ImageView close, menu;
    Statuser statuser;
    RevivDatabase database;
    String email, fname, lname;
    TextView txtUsername, txtEmail;

    private static String TAG = "BottomNavDrawerFragment";

    public BottomNavigationDrawerFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view =  inflater.inflate(R.layout.fragment_bottomsheet, container, false);
        txtUsername = view.findViewById(R.id.txtUsername);
        txtEmail = view.findViewById(R.id.txtEmail);
        navigationView = view.findViewById(R.id.navigation_view);
        database = RevivDatabase.getDatabase(getActivity());
        statuser = database.revivDao().getUserDetails();
        fname = statuser.getFname();
        lname = statuser.getLname();
        email = statuser.getEmail();
        txtEmail.setText(email);
        txtUsername.setText(fname+" "+lname);
        setRetainInstance(true);
        close = view.findViewById(R.id.imgClose);
        fragment = this;
        close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fragment.dismiss();
            }
        });
        navigationView.setItemIconTintList(null);
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                menuItem.setChecked(true);
                int id = menuItem.getItemId();
                FragmentManager manager;
                try {
                    manager = getActivity().getSupportFragmentManager();
                } catch (NullPointerException e) {
                    if (!isAdded()) return false;
                    manager = getChildFragmentManager();
                    Log.e(TAG, "onNavigationItemSelected: ", e);
                }
                switch (id){
                    case R.id.app_bar_incident:
                        navigationView.getMenu().findItem(id).setChecked(true);
                        manager.beginTransaction().replace(R.id.containerFrameLayout, new FragmentRevivIncidentDashboard()).commit();
                        Toast.makeText(getContext(), "Request Incident", Toast.LENGTH_SHORT).show();
                        fragment.dismiss();
                        break;
                    case R.id.app_bar_housecall:
                        navigationView.getMenu().findItem(id).setChecked(true);
                        manager.beginTransaction().replace(R.id.containerFrameLayout, new FragmentRevivHousecallDashboard()).commit();
                        fragment.dismiss();
                        Toast.makeText(getContext(), "Request Housecall", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.settings:
                        navigationView.getMenu().findItem(id).setChecked(true);
                        manager.beginTransaction().replace(R.id.containerFrameLayout, new FragmentRevivSettingsMain()).commit();
                        Toast.makeText(getActivity().getApplicationContext(), "Settings", Toast.LENGTH_SHORT).show();
                        fragment.dismiss();
                        break;

                }
                return true;
            }
        });

        return view;
    }

    @Override
    public void onDetach() {
        super.onDetach();

        try {
            Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
            childFragmentManager.setAccessible(true);
            childFragmentManager.set(this, null);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public NavigationView getNavigationView() {
        return navigationView;
    }
}
我的错误消息

09-13 00:26:32.996 28025-28025/com.package.name E/AndroidRuntime: 致命异常:主 进程:com.package.name,PID:28025 java.lang.IllegalStateException:尚未附加片段。 位于android.support.v4.app.Fragment.InstanceChildFragmentManager(Fragment.java:2386) 位于android.support.v4.app.Fragment.getChildFragmentManager(Fragment.java:842) 位于com.package.name.Fragments.BottomNavigationDrawerFragment$2.onNavigationItemSelected(BottomNavigationDrawerFragment.java:108) 位于android.support.design.widget.NavigationView$1.onMenuItemSelected(NavigationView.java:170) 位于android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:840) 在android.support.v7.view.menu.menuitemmpl.invoke(menuitemmpl.java:158)中 位于android.support.v7.view.menu.MenuBuilder.performitemation(MenuBuilder.java:991) 位于android.support.v7.view.menu.MenuBuilder.performitemation(MenuBuilder.java:981) 位于android.support.v7.view.menu.MenuBuilder.performIdentifierAction(MenuBuilder.java:977) 位于com.package.name.revio.resetNavDefault(revo.java:644) 位于com.package.name.Fragments.fragmentRevivationSettingsMain$1.onClick(fragmentRevivationSettingsMain.java:77) 在android.view.view.performClick上(view.java:6303) 在android.view.view$PerformClick.run(view.java:24828) 位于android.os.Handler.handleCallback(Handler.java:789) 位于android.os.Handler.dispatchMessage(Handler.java:98) 位于android.os.Looper.loop(Looper.java:164) 位于android.app.ActivityThread.main(ActivityThread.java:6798) 位于java.lang.reflect.Method.invoke(本机方法) 在com.android.internal.os.Zygote$MethodAndArgsCaller.run上(Zygote.java:240) 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)


首先在MainActivity中实现按钮单击事件,如下所示。然后假设在MainActivity中有BottomNavigationDrawerFragment实例,只需通过该实例获取视图,并在单击按钮时通过该视图调用setSelection导航菜单。确保在发出bottomNavDrawerFragment.show(..)调用后通过实例获取视图。否则您将出现NPE错误。

非常感谢您,费拉特。我尝试了您建议的解决方案,但最终决定在单击按钮时创建BottomNavFragment的新实例,并在创建后设置选择。这是非常粗糙的,但我想我可以把代码拿出来,并在代码发布后开发更全面的解决方案。(这是测试版)。我将发布一个更新,一旦我实现了你的解决方案,希望很快。我接受你的回答,因为我确信它会起作用。不客气,我希望它能有所帮助。请随时评论进一步的更新。