如何从 WebInterface 更改导航抽屉菜单项的可见性
How to change navigation drawer menu items visibility from WebInternface
我正在编写一个 android 应用程序,仅使用网络视图和网络界面。
我有一个带有菜单项的导航抽屉,我需要更改不同类型用户(f.e 版主、卖家等)的菜单可见性。为此,我从 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)
您需要从主线程更新 UI。使用 运行OnUiThread,您可以更新它。
runOnUiThread(new Runnable() {
@Override
public void run() {
// Update UI
}
});
Activity.runOnUiThread 文档
将 this 嵌套在方法中,然后将原始代码放入 运行 函数中。仅包含尽可能少的代码,否则您将开始破坏后台线程的目的。
我正在编写一个 android 应用程序,仅使用网络视图和网络界面。 我有一个带有菜单项的导航抽屉,我需要更改不同类型用户(f.e 版主、卖家等)的菜单可见性。为此,我从 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)
您需要从主线程更新 UI。使用 运行OnUiThread,您可以更新它。
runOnUiThread(new Runnable() {
@Override
public void run() {
// Update UI
}
});
Activity.runOnUiThread 文档
将 this 嵌套在方法中,然后将原始代码放入 运行 函数中。仅包含尽可能少的代码,否则您将开始破坏后台线程的目的。