我试图使最后一个MenuItem在“抽屉”菜单中不可见。尽管在Stackoverflow上使用existing solutions,我还是得到了一个空指针异常,并且不理解它。
navdrawer_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/faq_id"
        android:icon="@drawable/contact_support_24px"
        android:title="@string/frequently_asked_questions" />
    <item
        android:id="@+id/support_id"
        android:icon="@drawable/email_24px"
        android:title="@string/support_suggestions" />
    <item
        android:id="@+id/news_twitter_id"
        android:icon="@drawable/twitter"
        android:title="@string/news_twitter" />
    <item
        android:id="@+id/news_facebook_id"
        android:icon="@drawable/facebook_24px"
        android:title="@string/news_facebook" />
    <item
        android:id="@+id/signout_id"
        android:icon="@drawable/logout"
        android:title="@string/sign_out" />
</menu>
Activity 布局:
<layout>
    <androidx.drawerlayout.widget.DrawerLayout
        <LinearLayout
            <fragment/>
        </LinearLayout>

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/navViewVpn"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/nav_header"
            app:menu="@menu/navdrawer_menu" />
    </androidx.drawerlayout.widget.DrawerLayout>
</layout>
Activity 代码:
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val navView: NavigationView = findViewById(R.id.navViewVpn)
        val i = navView.headerCount // 1
        val header: View = navView.getHeaderView(0)
        val signout: MenuItem = header.findViewById(R.id.signout_id) // Crash
}
崩溃发生在最后一行,甚至无法在标题下找到signout_id。但为什么?
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.company.App.vpn.android, PID: 12008
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.company.App.vpn.android/com.company.App.vpn.android.VpnActivity}: java.lang.NullPointerException: header.findViewById(R.id.signout_id) must not be null
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
        at android.app.ActivityThread.access$800(ActivityThread.java:135)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5017)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException: header.findViewById(R.id.signout_id) must not be null

最佳答案

在此行中,我们尝试将View实例分配给MenuItem类型的变量。 MenuItem不会扩展View(因此不存在),因此此分配给我们带来了一些麻烦。

val signout: MenuItem = header.findViewById(R.id.signout_id)
捕获MenuItem绝对是正确的。但是, header 元素实际上是导航抽屉的单独元素,在这种情况下没有用。相反,我们可以使用navView实例获得对MenuItem的引用。然后,使用findItem方法,而不是findViewById
从那里可以根据需要以编程方式编辑菜单项。
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val navView: NavigationView = findViewById(R.id.navViewVpn)

        val signout: MenuItem = navView.menu.findItem(R.id.signout_id);

        // Edit the menu item as required
        signout.isVisible = false;
}
注意,对于任何用Java执行此操作的人,等效代码如下。
NavigationView navView = findViewById(R.id.nav_view_id);
MenuItem item = navView.getMenu().findItem(R.id.navItemId);

关于android - Android:无法访问DrawerLayout中的MenuItem,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/64292197/

10-13 03:27