隐藏/显示片段中的导航元素

Posted

技术标签:

【中文标题】隐藏/显示片段中的导航元素【英文标题】:Hiding/Showing Navigation Elements From A Fragment 【发布时间】:2020-03-10 18:53:47 【问题描述】:

我希望在用户未登录时从应用导航栏中隐藏“个人资料”菜单项。当用户最终登录时,我想做两件事:

    隐藏“登录”按钮 显示“个人资料”按钮

这应该很简单,尽管我不确定如何访问我希望关闭的这些菜单项,当我尝试关闭时,我不断收到 NullPointerExceptions。

我不能像我尝试过 MenuItem profileBtn= view.findViewById(R.id.nav_profile); profileBtn.setVisible(true); 那样通常只按 id 选择元素,因为它会抛出 NullPointerException

java.lang.NullPointerException: Attempt to invoke interface method 'android.view.MenuItem android.view.MenuItem.setVisible(boolean)' on a null object reference

这是 loginScreen.java 片段,我希望在其中显示配置文件按钮并在底部的“onClick”方法中隐藏登录按钮。


public class loginScreen extends Fragment implements View.OnClickListener

    private loginScreenText loginScreenText;
    EditText email;
    EditText password;
    NavigationView navigationView;
    Button button;
    SimpleAccountManager accountManager;
    Context mContext;

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        setHasOptionsMenu(true);

        mContext = getActivity().getApplicationContext();
        accountManager = new SimpleAccountManager(mContext);
        button = (Button) inflater.inflate(R.layout.login_page, container, false).findViewById(R.id.loginBtn);

        loginScreenText =
        ViewModelProviders.of(this).get(loginScreenText.class);
        View root = inflater.inflate(R.layout.login_page, container, false);
        final TextView textView = root.findViewById(R.id.text_share);
        button = root.findViewById(R.id.loginBtn);
        email = root.findViewById(R.id.email);
        navigationView = root.findViewById(R.id.nav_view);
        password = root.findViewById(R.id.password);
        button.setOnClickListener(this);

        return root;
    

    public void onClick(View view)

        if(view == button)
            User user;
            if(accountManager.getUserByEmail(email.getText().toString()) != null)
                user = accountManager.getUserByEmail(email.getText().toString());


/*              Attempt to reference the profile button which results in NullPointerException as shown 
                above*/

                MenuItem profileBtn= view.findViewById(R.id.nav_profile);
                profileBtn.setVisible(true);

                Fragment profile = new profileScreen(mContext);
                FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(((ViewGroup)(getView().getParent())).getId(), profile);
                fragmentTransaction.commit();


                //kill current fragment
                getFragmentManager().beginTransaction()
                        .remove(loginScreen.this).commit();


                accountManager.login(user, password.getText().toString());
               else
                loginScreenText.setmText("No user found with email: " + email.getText().toString());
            

        
    


这是 activity_main_drawer.xml

中的菜单项
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view"
    android:id="@+id/navMenu">

    <group android:checkableBehavior="single" >
        <item
            android:id="@+id/nav_home"
            android:icon="@drawable/ic_menu_camera"
            android:title="@string/menu_home" />
        <item
            android:id="@+id/nav_profile"
            android:icon="@drawable/ic_menu_gallery"
            android:title="Profile"
            android:visible="false"/>
        <item
            android:id="@+id/nav_polls"
            android:icon="@drawable/ic_menu_slideshow"
            android:title="View Polls" />
        <item
            android:id="@+id/nav_patients"
            android:icon="@drawable/ic_menu_manage"
            android:title="View Patients" />
    </group>

    <item android:title="Log In!">
        <menu>
            <item
                android:id="@+id/nav_login"
                android:icon="@drawable/ic_menu_share"
                android:title="Login" />
            <item
                android:id="@+id/nav_login_sp"
                android:icon="@drawable/ic_menu_share"
                android:title="Login as SP" />
        </menu>
    </item>

</menu>

提前感谢任何对如何解决这个问题提出建议的人!

【问题讨论】:

【参考方案1】:

您需要先获取导航视图,然后获取其菜单,然后从那里获取项目,而不是直接使用 findViewById 获取菜单项。

换句话说:

NavigationView navigationView = findViewById(R.id.navigation_view); //use the proper id
Menu menu = navigationView.getMenu();
MenuItem menuItem = menu.findItem(R.id.nav_profile);

【讨论】:

我运行后得到了这个java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Menu com.google.android.material.navigation.NavigationView.getMenu()' on a null object reference 能把导航视图所在的xml贴一下吗?

以上是关于隐藏/显示片段中的导航元素的主要内容,如果未能解决你的问题,请参考以下文章

Android 全屏片段不显示导航和状态栏后面的元素

隐藏子屏幕/片段的android底部导航视图

如何在滚动列表视图上显示/隐藏底部导航视图?

如何使用导航从其他片段隐藏主机活动中的视图

带有片段的 Android Studio 导航抽屉。工具栏隐藏在下一个片段活动或页面中

框架布局接管屏幕并隐藏底部导航和工具栏