【发布时间】:2026-02-20 02:00:02
【问题描述】:
当我使用onCreateOptionsMenu 或onOptionsItemSelected 方法时,我可以轻松做到这一点。
但我在屏幕某处有一个按钮,单击该按钮时,它应该启用/禁用上下文菜单项。
【问题讨论】:
标签: android contextmenu menuitem
当我使用onCreateOptionsMenu 或onOptionsItemSelected 方法时,我可以轻松做到这一点。
但我在屏幕某处有一个按钮,单击该按钮时,它应该启用/禁用上下文菜单项。
【问题讨论】:
标签: android contextmenu menuitem
我所做的是在onCreateOptionsMenu 保存对菜单的引用。这类似于 nir 的答案,除了我没有保存每个单独的项目,而是保存了整个菜单。
声明一个菜单Menu toolbarMenu;。
然后在onCreateOptionsMenu将菜单保存到您的变量中
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.main_menu, menu);
toolbarMenu = menu;
return true;
}
现在您可以随时访问您的菜单及其所有项目。
toolbarMenu.getItem(0).setEnabled(false);
【讨论】:
一个老问题的更现代的答案:
MainActivity.kt
private var myMenuIconEnabled by Delegates.observable(true) { _, old, new ->
if (new != old) invalidateOptionsMenu()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.my_button).setOnClickListener { myMenuIconEnabled = false }
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main_activity, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
menu.findItem(R.id.action_my_action).isEnabled = myMenuIconEnabled
return super.onPrepareOptionsMenu(menu)
}
menu_main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_my_action"
android:icon="@drawable/ic_my_icon_24dp"
app:iconTint="@drawable/menu_item_icon_selector"
android:title="My title"
app:showAsAction="always" />
</menu>
menu_item_icon_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?enabledMenuIconColor" android:state_enabled="true" />
<item android:color="?disabledMenuIconColor" />
attrs.xml
<resources>
<attr name="enabledMenuIconColor" format="reference|color"/>
<attr name="disabledMenuIconColor" format="reference|color"/>
</resources>
styles.xml or themes.xml
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="disabledMenuIconColor">@color/white_30_alpha</item>
<item name="enabledMenuIconColor">@android:color/white</item>
【讨论】:
如果菜单可见
menu.findItem(R.id.id_name).setVisible(true);
如果隐藏菜单
menu.findItem(R.id.id_name).setVisible(false);
【讨论】:
如何更新当前菜单以在 AsyncTask 完成时启用或禁用项目。
在我的用例中,我需要在 AsyncTask 加载数据时禁用我的菜单,然后在加载所有数据后,我需要再次启用所有菜单才能让用户使用它。
这会阻止应用在加载数据时让用户点击菜单项。
首先,我声明一个状态变量,如果该变量为0,则显示菜单,如果该变量为1,则隐藏菜单。
private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.
然后在我的onCreateOptionsMenu() 中检查这个变量,如果它是 1,我禁用我的所有项目,如果不是,我就全部显示它们
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_galeria_pictos, menu);
if(mMenuState==1){
for (int i = 0; i < menu.size(); i++) {
menu.getItem(i).setVisible(false);
}
}else{
for (int i = 0; i < menu.size(); i++) {
menu.getItem(i).setVisible(true);
}
}
return super.onCreateOptionsMenu(menu);
}
现在,当我的 Activity 启动时,onCreateOptionsMenu() 将只被调用一次,并且我的所有项目都将消失,因为我在开始时为它们设置了状态。
然后我创建一个 AsyncTask 我在我的onPostExecute() 中将该状态变量设置为 0
这一步很重要!
当您调用invalidateOptionsMenu(); 时,它将重新启动onCreateOptionsMenu();
所以,在将我的状态设置为 0 之后,我只是重绘了所有菜单,但这次我的变量为 0 ,也就是说,所有的菜单将在所有异步过程完成后显示,然后我的用户可以使用菜单。
public class LoadMyGroups extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
mMenuState = 1; //you can set here the state of the menu too if you dont want to initialize it at global declaration.
}
@Override
protected Void doInBackground(Void... voids) {
//Background work
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mMenuState=0; //We change the state and relaunch onCreateOptionsMenu
invalidateOptionsMenu(); //Relaunch onCreateOptionsMenu
}
}
【讨论】:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_id:
//Your Code....
item.setEnabled(false);
break;
}
return super.onOptionsItemSelected(item);
}
【讨论】:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.home, menu);
return false;
}
【讨论】:
简化@Vikas 版本
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
return true;
}
【讨论】:
无论如何,the documentation 涵盖了所有内容。
活动创建后,
onCreateOptionsMenu()方法被调用 仅一次,如上所述。这 系统保留和重复使用Menu你 在此方法中定义,直到您的 活动被破坏。如果你想 之后随时更改选项菜单 它是第一次创建的,您必须覆盖onPrepareOptionsMenu()方法。 这会将 Menu 对象传递给您 目前存在。这很有用,如果 您想删除、添加、禁用或 启用菜单项取决于 您的应用程序的当前状态。
例如
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
if (isFinalized) {
menu.getItem(1).setEnabled(false);
// You can also use something like:
// menu.findItem(R.id.example_foobar).setEnabled(false);
}
return true;
}
在 Android 3.0 及更高版本上,当菜单项出现在操作栏中时,选项菜单被视为始终处于打开状态。当有事件发生,你想进行菜单更新时,你必须调用invalidateOptionsMenu()来请求系统调用onPrepareOptionsMenu()。
【讨论】:
setEnable() 确实会改变您按下此菜单时发生的情况,但不会改变它的外观(Android 开发人员出了什么问题?)。因此,禁用 并 更改标题会更清楚,或者最好只使 MenuItem 不可见。
false 以完全禁用菜单。
最佳解决方案 当您在导航抽屉上执行时
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(0,false);
return true;
}
【讨论】:
在所有 android 版本上,最简单的方法:使用它来显示一个菜单操作图标为禁用,并使其 FUNCTION 为禁用:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item = menu.findItem(R.id.menu_my_item);
if (myItemShouldBeEnabled) {
item.setEnabled(true);
item.getIcon().setAlpha(255);
} else {
// disabled
item.setEnabled(false);
item.getIcon().setAlpha(130);
}
}
【讨论】:
通常可以在运行时更改视图的属性:
(Button) item = (Button) findViewById(R.id.idBut);
然后……
item.setVisibility(false)
但是
如果您想从 ContextMenu 修改选项的可见性,按下按钮,您可以激活一个标志,然后在 onCreateContextMenu 中您可以执行以下操作:
@Override
public void onCreateContextMenu(ContextMenu menu,
View v,ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle(R.string.context_title);
if (flagIsOn()) {
addMenuItem(menu, "Option available", true);
} else {
Toast.makeText(this, "Option not available", 500).show();
}
}
希望对你有帮助
【讨论】:
onCreateContextMenu 方法中更改它的问题。但我想从这个方法访问上下文菜单。
onCreateContextMenu 只会被调用一次,但我可以多次单击按钮来启用/禁用菜单项。
您可以在创建选项菜单时将项目保存为变量,然后随意更改其属性。
private MenuItem securedConnection;
private MenuItem insecuredConnection;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.connect_menu, menu);
securedConnection = menu.getItem(0);
insecuredConnection = menu.getItem(1);
return true;
}
public void foo(){
securedConnection.setEnabled(true);
}
【讨论】:
onPrepareOptionsMenu?