简体   繁体   English

在Android上打开DrawerLayout时如何编辑导航菜单项标题

[英]How to edit a navigation menu item title while the DrawerLayout is open on Android

On Android, when a NavigationView is created in a DrawerLayout , the title of individual MenuItems can be modified by 1) getting handles for the MenuItems in the main activity: 在Android上,当在DrawerLayout创建NavigationView时,可以通过以下方式修改单个MenuItems的标题:1)在主活动中获取MenuItems句柄:

// Get a handle for the navigation view.
NavigationView navigationView = findViewById(R.id.navigationview);

// Get handles for the navigation menu items.
final Menu navigationMenu = navigationView.getMenu();
final MenuItem navigationFirstMenuItem = navigationMenu.getItem(0);
final MenuItem navigationSecondMenuItem = navigationMenu.getItem(1);
final MenuItem navigationThirdMenuItem = navigationMenu.getItem(2);

and 2) modifying the titles of the menu items when the drawer is opened using a DrawerListener : 和2)使用DrawerListener打开抽屉时修改菜单项的标题:

// The drawer listener is used to update the navigation menu.
drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
    @Override
    public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
    }

    @Override
    public void onDrawerOpened(@NonNull View drawerView) {
    }

    @Override
    public void onDrawerClosed(@NonNull View drawerView) {
    }

    @Override
    public void onDrawerStateChanged(int newState) {
        if ((newState == DrawerLayout.STATE_SETTLING) || (newState == DrawerLayout.STATE_DRAGGING)) {  // A drawer is opening or closing.
            // Update the title of the menu items.
            navigationFirstMenuItem.setTitle(getString(R.string.newString));
            navigationSecondMenuItem.setEnabled(false);
            navigationThirdMenuItem.setTitle(getString(R.string.title) + " - " + counterInt);
            }
        }
    });

However, once the drawer is open, attempting to change the title of one of the menu items from a part of the main activity running on a different thread results in the following error, which crashes the app: 但是,一旦打开抽屉,尝试从运行在不同线程上的主要活动的一部分更改菜单项之一的标题,则会导致以下错误,从而使应用程序崩溃:

W/System.err: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

For example, this error can be produced by attempting to update a navigation menu item from inside WebViewClient.shouldInterceptRequest() as follows: 例如,尝试从WebViewClient.shouldInterceptRequest()内部更新导航菜单项,可能会产生此错误,如下所示:

// Get a handle for the WebView.
WebView webView = findViewById(R.id.webview);

// Set a WebViewClient.
webView.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url){
        navigationFirstMenuItem.setTitle(getString(R.string.newString));
        navigationSecondMenuItem.setEnabled(false);
        navigationThirdMenuItem.setTitle(getString(R.string.title) + " - " + counterInt);
    }
}

The question is how to update a menu item, for example, having a counter that increments in one of the titles, while the navigation drawer is open and the event that needs to update the menu item is running on a different thread. 问题是如何更新菜单项,例如,在打开导航抽屉且需要更新菜单项的事件在不同线程上运行的同时,其中一个计数器在标题之一中递增。

As suggested by @MikeM., the solution to the problem is to use Activity.runOnUiThread() to update the navigation from the same thread that created it. 如@MikeM。所建议,解决该问题的方法是使用Activity.runOnUiThread()从创建它的同一线程更新导航。 Specifically, the following code works for me. 具体来说,以下代码对我有用。

// Get a handle for the activity.  This is used to update the menu item titles while the navigation menu is open.
Activity activity = this;

// Get a handle for the WebView.
WebView webView = findViewById(R.id.webview);

// Set a WebViewClient.
webView.setWebViewClient(new WebViewClient() {
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView view, String url){
        // Update the menu items' titles from the UI thread.
        activity.runOnUiThread(() -> {
            navigationFirstMenuItem.setTitle(getString(R.string.newString));
            navigationSecondMenuItem.setEnabled(false);
            navigationThirdMenuItem.setTitle(getString(R.string.title) + " - " + counterInt);
        });
    }
}

The key to understanding this problem is that the navigation view is created by the UI thread. 理解此问题的关键是导航视图是由UI线程创建的。 That seems obvious in hindsight, but the error message doesn't specifically state that, and the behavior had initially led me to believe that there was some dedicated DrawerLayout thread that could only be accessed via the DrawerLayout listener. 在事后看来,这似乎很明显,但是错误消息并未具体说明这一点,并且这种行为最初使我相信有一些专用的DrawerLayout线程只能通过DrawerLayout侦听器进行访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 项目菜单标题长于DrawerLayout - Item menu title longer than DrawerLayout Android中的导航抽屉菜单项标题颜色 - Navigation Drawer Menu Item Title Color in Android 如何在android中单击DrawerLayout navigationView项目打开活动? - How to open an activity on click of a DrawerLayout navigationView item in android? android DrawerLayout导航无需单击DrawerLayout项即可重新加载片段 - android DrawerLayout navigation Fragment reload without click on DrawerLayout item 如何在Android中以编程方式设置图标和导航抽屉菜单项标题之间的边距? - How to programmatically set the margin between icon and title of menu item of Navigation Drawer in Android? 如何从导航抽屉菜单项获取标题 - How to get the title from Navigation drawer menu item 在Android中完成活动后,如何重置DrawerLayout导航项图标和文本颜色? - How to reset DrawerLayout navigation item icon and text colour when activity finished in Android? 单击导航抽屉默认菜单上的项目时如何打开另一个菜单 - how to open another menu on click of item on the default menu of navigation drawer Android-如何刷新导航抽屉的菜单项 - Android - How to refresh the menu item of Navigation Drawer 底部导航视图菜单项标题大小 - Bottom Navigation View menu item title size
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM