如何从WebInternface更改导航抽屉菜单项的可见性

时间:2018-12-17 15:34:39

标签: java android android-webview navigation-drawer

我正在仅使用网络视图和网络界面编写一个android应用。 我有一个带有菜单项的导航抽屉,并且我需要更改菜单的可见性,以适应不同类型的用户(例如主持人,卖家等)。为此,我从WebInterface调用js中的setItemVisible()函数,但是它不起作用。 这是我的WebInterface代码

package com.example.samosval;

import ...

class WebAppInterface{
Context mContext;
private DomainLoadStoreParameter resources;

/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
    mContext = c;
}

@JavascriptInterface
public void setItemVisible(String name) {
    try {
        NavigationView navigationView = (NavigationView) ((Activity) mContext).findViewById(R.id.nav_view);
        MenuItem menuItem = navigationView.getMenu().findItem(getResId(name, R.id.class));
        menuItem.setVisible(true);
    } catch (Exception e) {
        Log.e("TAGIF", "setItemVisible: ", e);
    }
}

public static int getResId(String resName, Class<?> c) {

    try {
        Field idField = c.getDeclaredField(resName);
        return idField.getInt(idField);
    } catch (Exception e) {
        e.printStackTrace();
        return -1;
    }
}
}

但是有这样的错误

12-17 21:07:58.406 2229-2386/com.arystankaliakparov.samosval E/TAGIF: setItemVisible: 
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7234)
    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1070)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.support.v4.widget.DrawerLayout.requestLayout(DrawerLayout.java:1303)
    at android.view.View.requestLayout(View.java:17932)
    at android.view.View.requestLayout(View.java:17932)
    at android.support.v7.widget.RecyclerView.requestLayout(RecyclerView.java:4202)
    at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onChanged(RecyclerView.java:5286)
    at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyChanged(RecyclerView.java:11997)
    at android.support.v7.widget.RecyclerView$Adapter.notifyDataSetChanged(RecyclerView.java:7070)
    at android.support.design.internal.NavigationMenuPresenter$NavigationMenuAdapter.update(NavigationMenuPresenter.java:474)
    at android.support.design.internal.NavigationMenuPresenter.updateMenuView(NavigationMenuPresenter.java:114)
    at android.support.v7.view.menu.MenuBuilder.dispatchPresenterUpdate(MenuBuilder.java:298)
    at android.support.v7.view.menu.MenuBuilder.onItemsChanged(MenuBuilder.java:1069)
    at android.support.v7.view.menu.MenuBuilder.onItemVisibleChanged(MenuBuilder.java:1108)
    at android.support.v7.view.menu.MenuItemImpl.setVisible(MenuItemImpl.java:665)
    at com.arystankaliakparov.samosval.WebAppInterface.setItemVisible(WebAppInterface.java:46)
    at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
    at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:53)
    at android.os.Handler.dispatchMessage(Handler.java:111)
    at android.os.Looper.loop(Looper.java:194)
    at android.os.HandlerThread.run(HandlerThread.java:61)

1 个答案:

答案 0 :(得分:0)

您需要从主线程更新UI。使用runOnUiThread,即可对其进行更新。

runOnUiThread(new Runnable() {
 @Override
 public void run() {
    // Update UI
 }
});

Activity.runOnUiThread文档

将此方法嵌套在方法内部,然后将原始代码放入run函数中。仅包含尽可能少的代码,否则您将开始违反后台线程的目的。