Ответы:
Во всяком случае, документация охватывает все.
После создания действия
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()
.
false
чтобы полностью отключить меню.
Во всех версиях Android самый простой способ: используйте это, чтобы ПОКАЗАТЬ значок действия в меню как отключенный И сделать его ФУНКЦИОНАЛЬНЫМ как отключенным:
@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);
}
}
Вы можете сохранить элемент как переменную при создании меню параметров, а затем изменить его свойства по желанию.
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
?
упростить версию @Vikas
@Override
public boolean onPrepareOptionsMenu (Menu menu) {
menu.findItem(R.id.example_foobar).setEnabled(isFinalized);
return true;
}
Как обновить текущее меню, чтобы включить или отключить элементы после выполнения 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, где устанавливаю для этой переменной состояния значение 0 в моем onPostExecute()
Этот шаг очень важен!
Когда вы позвоните, 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 onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(0,false);
return true;
}
Более современный ответ на старый вопрос:
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>
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item_id:
//Your Code....
item.setEnabled(false);
break;
}
return super.onOptionsItemSelected(item);
}
Я сохранил ссылку на меню в 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);
@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;
}
Если отображается меню
menu.findItem(R.id.id_name).setVisible(true);
Если скрыть меню
menu.findItem(R.id.id_name).setVisible(false);
Как правило, можно изменить свойства ваших представлений во время выполнения:
(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
будет вызываться только один раз, но я могу нажимать кнопку много времени, чтобы включить / отключить пункт меню.
setEnable()
меняет то, что происходит при нажатии на это меню, но не меняет его внешний вид (что не так, разработчики Android?). Так что понятнее либо отключить и изменить заголовок, либо, желательно, просто сделатьMenuItem
невидимым.