Изменение значка меню на панели действий в зависимости от открытого фрагмента
У меня есть этот пункт в моем меню опций:
<item
android:id="@+id/opt_mnu_action"
android:icon="@android:drawable/ic_dialog_info"
android:orderInCategory="1"
android:showAsAction="ifRoom"
android:title="New">
</item>
Меню, созданное в основном FragmentActivity. Я хочу изменить этот значок элемента программно в зависимости от открытого фрагмента и, очевидно, иметь разные действия, когда пользователь нажимает эту кнопку. Я попробовал несколько вещей, но ничего не получилось. Последнее, что я пробовал, это этот код в методе Fragment onCreateView:
MenuItem mi = (MenuItem) view.findViewById(R.id.opt_mnu_action);
mi.setIcon(R.drawable.ico_1);
Но мое приложение разбилось. Так есть способ сделать это?
** UPDATE **
Вот то, что я пытаюсь сделать сейчас, все в моей основной основной FragmentActivity:
Прежде всего, у меня есть MenuItem action_button;
в моем представлении иерархии. Затем в моем методе onCreateOptionsMenu
я его создаю:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
action_button = menu.findItem(R.id.opt_mnu_action);
return super.onCreateOptionsMenu(menu);
}
Затем я создал эту функцию для изменения значка в соответствии с открытой вкладкой:
public void change_action_button_icon(int tab_position)
{
switch(tab_position)
{
case 0:
action_button.setIcon(R.drawable.ico_1);
break;
case 1:
action_button.setIcon(R.drawable.ico_2);
break;
case 2:
action_button.setIcon(R.drawable.ico_3);
break;
}
invalidateOptionsMenu();
}
И я называю это своим методом onTabSelected
:
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
setTab_position(tab.getPosition());
change_action_button_icon(tab.getPosition());
}
Но как только я запустил приложение, он сработает. Я получаю ошибку NullPointerException
в этой строке:
action_button.setIcon(R.drawable.ico_1);
Моя догадка - это происходит потому, что было запрошено изменение значка до того, как был создан экземпляр action_button
. Но я не знаю, как его преодолеть...
Ответы
Ответ 1
Используйте это, чтобы получить ссылку на пункт меню:
menu.findItem(resourceId).setIcon(drawableId);
Вы должны поместить код для изменения значка в onCreateOptionsMenu().
Пожалуйста, обратитесь к моему примеру ниже:
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.option_menu, menu);
if (needToChangeMenuItem){
menu.findItem(resourceId).setIcon(drawableId);
}
manageMenuIcon(menu);
needToChangeMenuItem = false;
return true;
}
public void manageMenuIcon(Menu menu){
if (bluetoothIconOn){
menu.findItem(R.id.secure_connect_scan).setIcon(R.drawable.bluetoothon);
} else
menu.findItem(R.id.secure_connect_scan).setIcon(R.drawable.bluetoothoff);
if (gpsIconOn)
menu.findItem(R.id.gps).setIcon(R.drawable.gps);
else
menu.findItem(R.id.gps).setVisible(false);
if (slipAndDropIconOn)
menu.findItem(R.id.fall).setIcon(R.drawable.fall);
else
menu.findItem(R.id.fall).setVisible(false);
if (fesConnectIconOn)
menu.findItem(R.id.fesConnection).setIcon(R.drawable.fesconnect);
else
menu.findItem(R.id.fesConnection).setVisible(false);
}
public void changeMenuItem(int resId, int draId){
needToChangeMenuItem = true;
resourceId = resId;
drawableId = draId;
invalidateOptionsMenu();
}
Ответ 2
MenuItem mi = (MenuItem) view.findViewById(R.id.opt_mnu_action);
mi.setIcon(R.drawable.ico_1);
В вашем фрагменте onCreateOptionsMenu
загрузите это меню и сохраните ссылку на элемент меню (он не является частью иерархии представлений фрагментов, поэтому вы не можете использовать findViewById).
Когда вы готовы обновить значок, используйте mi.setIcon(R.drawable.ico_1);
и вызовите invalidateOptionsMenu()
.
ОБНОВЛЕНО:
return super.onCreateOptionsMenu(menu);
Это фактически вернет false, так как базовая реализация этого не делает. Вместо этого пропустите его или просто вызовите super.onCreateOptionsMenu(menu);
, сначала сделайте свой материал, а затем верните true.