更改由 xml 布局制作的工具栏菜单上的菜单项
Changing menu items on a toolbar menu made from a xml layout
所以我的应用程序中有这个工具栏,我想根据用户是否登录显示不同的菜单项。当用户登录或注销时,我想更新我的布局,现在是工具栏菜单来表示更改。但出于某种原因,我的菜单项根本没有被删除,无论登录状态如何,所有菜单项始终可见。
我的菜单项:
<menu
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_add"
android:icon="@drawable/ic_action_add"
android:title="@string/action_add"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_login"
android:icon="@drawable/ic_action_logged_out"
android:title="@string/action_log_in"
app:showAsAction="always"/>
<item
android:id="@+id/action_logout"
android:icon="@drawable/ic_action_logged_in"
android:title="@string/action_log_out"
app:showAsAction="always"/>
</menu>
第一个菜单项应该只对已登录的用户可见。而且我想这是不言自明的,但我只希望其中一个日志 in/out 按钮根据登录可见状态。
我的Java代码:
protected void initializeToolbar(){
myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
menu = myToolbar.getMenu();
resetToolbarMenu();
myToolbar.setOnMenuItemClickListener(this);
}
private void resetToolbarMenu(){
menu.clear();
getMenuInflater().inflate(R.menu.menu, menu);
if(loginPrefs.getBoolean("login", false)) { //loginPrefs is reference to a SharedPreference object
menu.removeItem(1);
} else {
menu.removeItem(2);
menu.removeItem(0);
}
}
我有两种方法的原因是我只想设置一次工具栏和侦听器,但我希望能够在用户每次登录时更改菜单 in/out 而无需重新加载页面。
成功登录后,将再次调用resetToolbarMenu()
方法。
我想 menu.remove(0)
不会更新 UI,但如果不先膨胀菜单对象然后从工具栏中获取它,我找不到另一种方法来访问我的菜单对象,我假设inflation 决定哪些项目可见。基本上,我找不到一种方法在膨胀或以膨胀以外的其他方式更新 UI 之前删除任何菜单项。
解决方案:
我将 java 代码更改为如下内容:
protected void initializeToolbar(){
myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu); // Don't know if this is necessary or if returning true is prefered.
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(loginPrefs.getBoolean("login", false)) {
menu.getItem(0).setVisible(true);
menu.getItem(1).setVisible(false);
menu.getItem(2).setVisible(true);
} else {
menu.getItem(0).setVisible(false);
menu.getItem(1).setVisible(true);
menu.getItem(2).setVisible(false);
}
return true;
}
我还必须在 logout/login 上调用 invalidateOptionsMenu()
来更新 toolbar/menu。但是,每当您打开工具栏本身未显示的项目的菜单时,也会自动调用 onPrepareOptionsMenu()。
PS: OnCreateOptionsMenu
和 OnPrepareOptionsMenu
不会被使用,除非你记得 setSupportActionBar(myToolbar)
因为我忘了。
您必须覆盖 activity 中的 onPrepareOptionsMenu 才能更改菜单中的项目。
来自文档:
准备要显示的屏幕标准选项菜单。每次显示菜单时,都会在显示菜单之前调用它。您可以使用此方法高效地 enable/disable 项目或以其他方式动态修改内容。
您可以通过覆盖 onCreateOptionsMenu
创建选项菜单。您可以创建 2 xml 并根据您的逻辑对其中之一进行膨胀。要强制重绘菜单,您可以调用 invalidateOptionsMenu
.
例如
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
if (login) {
inflater.inflate(R.menu.login_menu, menu);
} else {
inflater.inflate(R.menu.logout_menu, menu);
}
return true;
}
并在外部更改标志并强制重绘
login = false; // or true
invalidateOptionsMenu();
所以我的应用程序中有这个工具栏,我想根据用户是否登录显示不同的菜单项。当用户登录或注销时,我想更新我的布局,现在是工具栏菜单来表示更改。但出于某种原因,我的菜单项根本没有被删除,无论登录状态如何,所有菜单项始终可见。
我的菜单项:
<menu
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_add"
android:icon="@drawable/ic_action_add"
android:title="@string/action_add"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_login"
android:icon="@drawable/ic_action_logged_out"
android:title="@string/action_log_in"
app:showAsAction="always"/>
<item
android:id="@+id/action_logout"
android:icon="@drawable/ic_action_logged_in"
android:title="@string/action_log_out"
app:showAsAction="always"/>
</menu>
第一个菜单项应该只对已登录的用户可见。而且我想这是不言自明的,但我只希望其中一个日志 in/out 按钮根据登录可见状态。
我的Java代码:
protected void initializeToolbar(){
myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
menu = myToolbar.getMenu();
resetToolbarMenu();
myToolbar.setOnMenuItemClickListener(this);
}
private void resetToolbarMenu(){
menu.clear();
getMenuInflater().inflate(R.menu.menu, menu);
if(loginPrefs.getBoolean("login", false)) { //loginPrefs is reference to a SharedPreference object
menu.removeItem(1);
} else {
menu.removeItem(2);
menu.removeItem(0);
}
}
我有两种方法的原因是我只想设置一次工具栏和侦听器,但我希望能够在用户每次登录时更改菜单 in/out 而无需重新加载页面。
成功登录后,将再次调用resetToolbarMenu()
方法。
我想 menu.remove(0)
不会更新 UI,但如果不先膨胀菜单对象然后从工具栏中获取它,我找不到另一种方法来访问我的菜单对象,我假设inflation 决定哪些项目可见。基本上,我找不到一种方法在膨胀或以膨胀以外的其他方式更新 UI 之前删除任何菜单项。
解决方案:
我将 java 代码更改为如下内容:
protected void initializeToolbar(){
myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu); // Don't know if this is necessary or if returning true is prefered.
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(loginPrefs.getBoolean("login", false)) {
menu.getItem(0).setVisible(true);
menu.getItem(1).setVisible(false);
menu.getItem(2).setVisible(true);
} else {
menu.getItem(0).setVisible(false);
menu.getItem(1).setVisible(true);
menu.getItem(2).setVisible(false);
}
return true;
}
我还必须在 logout/login 上调用 invalidateOptionsMenu()
来更新 toolbar/menu。但是,每当您打开工具栏本身未显示的项目的菜单时,也会自动调用 onPrepareOptionsMenu()。
PS: OnCreateOptionsMenu
和 OnPrepareOptionsMenu
不会被使用,除非你记得 setSupportActionBar(myToolbar)
因为我忘了。
您必须覆盖 activity 中的 onPrepareOptionsMenu 才能更改菜单中的项目。
来自文档:
准备要显示的屏幕标准选项菜单。每次显示菜单时,都会在显示菜单之前调用它。您可以使用此方法高效地 enable/disable 项目或以其他方式动态修改内容。
您可以通过覆盖 onCreateOptionsMenu
创建选项菜单。您可以创建 2 xml 并根据您的逻辑对其中之一进行膨胀。要强制重绘菜单,您可以调用 invalidateOptionsMenu
.
例如
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
if (login) {
inflater.inflate(R.menu.login_menu, menu);
} else {
inflater.inflate(R.menu.logout_menu, menu);
}
return true;
}
并在外部更改标志并强制重绘
login = false; // or true
invalidateOptionsMenu();