Урок 14. Menu Android: добавляем иконки и чекбоксы, программно добавляем и скрываем пункты меню
Вставка
- Опубліковано 15 чер 2015
- Подпишись на Продвинутые курсы по созданию мобильных приложений и игр для андроид на языках Java и Kotlin: www.fandroid.info/category/pr...
Как программно добавить или скрыть пункты в меню, как сортировать и группировать пункты меню, как добавить иконку и вывести пункт меню на Toolbar или ActionBar, как добавить чекбокс для пункта меню андроид приложения. Познакомимся с методами onPrepareOptionsMenu, setGroupVisible, setCheckable, setChecked, isChecked.
Весь плейлист: • Уроки по основам разра...
Конструкции выбора в языке Java: if…else, switch: www.fandroid.info/konstruktsii...
Скачать исходный код проекта: yadi.sk/d/Wb6o1AFvhJ4KV
Группа взаимопомощи Вконтакте для начинающих ANDROID разработчиков и программистов: www.fandroid.info/gruppa-vzaim...
Скачать видеоуроки: www.fandroid.info/skachat-vide...
Поддержите наш проект: www.fandroid.info/spasibo-za-v...
#android #AndroidStudio #startandroid - Наука та технологія
Три месяца назад я начал заниматься по этому видеокурсу. И чем дальше, тем сложнее, а все потому что я плохо знал Java. И как раз на этом видео я пришел в тупик и начал изучать вплотную Java. И сегодня опять смотрю ваши курсы и все намного понятнее и смог решить ДЗ! Так что ребята наберитесь терпения и учите язык! А автору большое спасибо!
Как успехи?
Интересные домашние задания даёте.
Побольше бы их!
Это лучшие уроки по Android !!! Я был в поисках около 4 месяцев нормальных курсов на русском (на инглише и так достаточно хороших). Эти лучшие бесплатные уроки по Android (вводный курс гикбрейнс так же тоже неплох, но он только вводный, а дальше платно!!! Спасибо Вам, Виталий, за информацию страждущим!! Всё очень понятно, конструктивно и последовательно, особенно когда уже есть небольшой опыт кодинга (можете ради интереса сравнить подачу материала, например, с батуршиновым тимуром вроде, когда он уже на первых уроках учит переключать активити с передачей параметров, ни хрена не обьяснив ничего, а уроки у него платные.
отличные уроки! жду новых серий!
Самое лаконичное решение как по мне:
В методе onPrepareOptionsMenu пишем ДВЕ строчки:menu.findItem(R.id.action_settings).setVisible(check2.isChecked());
invalidateOptionsMenu();
(Чекбокс объявляем в классе MainActivity, инициализируем (находим) в методе onCreate)
погуглите про метод invalidateOptionsMenu(); - полезная штука
Странно, у меня работает и так:
public boolean onPrepareOptionsMenu (Menu menu){
invalidateOptionsMenu();//обновить опции
MenuItem action_mail = menu.findItem(R.id.action_mail);//находим пунк меню
if (chb2.isChecked()){//если чекбокс2 установлен то видим пункт меню и наоборот
action_mail.setVisible(true);
}else {
action_mail.setVisible(false);
}
menu.setGroupVisible(R.id.group1, chb1.isChecked());//здесь мы делаем группу пунктов из меню видимой
return super.onPrepareOptionsMenu(menu);
}
не понимаю почему но не работает метод invalidateOptionsMenu(). Перепробовал его в разных местах кода и в любом случае иконка settings исчезает и появляется только после вызова меню (то есть запуска метода onPrepareOptionsMenu)
Провозился два вечера с домашним заданием, но пошло на пользу. Сначала сделал, как пишут внизу - объявил новую переменную типа Меню, потом к ней привязал нужную опцию и ставил на onClicklistener визибл Да/нет, таким образом получилось, что:
1. Мы создаём меню в одном месте метод "onCreateOptionsMenu"
2. Условия отображения пунктов меню в другом метсе метод "onPrepareOptionsMenu"
3. Условие отображения одного из пункта висит вообще на чекбоксе, точнее на слушателе.
А теперь мысленно расширяем проект и количество контроллов (вьюх) и понимаем, что в случае необходимости переписать логику отображения меню нам придётся рыскать по всему коду Activity и наверняка что-то пропустим.
Короче я решил, что все условия отображения меню (логика) должна быть в одном месте. Логично, если это метод "onPrepareOptionsMenu".
Теперь вопрос, как вызвать этот метод при активации View?
После двух вечеров мучений я нашёл / подсказали метод "invalidateOptionsMenu", который вызывает метод "onPrepareOptionsMenu", т.е. проверяет все условия, находящиеся в одной куче, и отрисовывает меню заново.
Ну а слушатель выглядит так:
case R.id.chbMenu: // ищем наш контролл
invalidateOptionsMenu(); // вызываем метод
break;
p.s. там где говорится про обработку одного меню, и конструкцию if than, придумал вот такую штуку:
menu.findItem(R.id.menuItem1).setVisible(chbItem.isChecked());
помещается в одну строчку, никаких If Than и всё такое.
Фух,наконец-то догнал как сделать ДЗ. Получилось,автор молоток!
Виталий, а таки ж хотелось бы увидеть твой вариант кода! ))
Здравствуйте, у вас во время выбора иконки рядом с названием появляется окно предварительного просмотра изображений. подскажите пожалуйста как его установить у себя. P.S. может я не понятно выразился окно появляется на видео на 3.20 минуте.
Создать view элементы и подобное можно 2мя способами - через xml и через java. Вопрос - каким способом лучше пользоваться? Есть ли разница вообще - в плане нагрузки там или еще чего.
как поставить свою иконку в action bar на item1, в drawable вставляю myIcon.png
если прописать
А скажите, если мы создали меню в java-классе (menu.add()) то нам в menu.XML надо этот пункт создавать ?!
А то получается хаос какойто. часть менюшек в коде а часть в хмл-е.
А как изменить сетку меню?Сейчас стоит 4х5 а хотелось бы 5х5 сделать.Заранее благодарю.
Спасибо что тратите своё время.
Уважаемый автор, можно узнать где можно глянуть все встроенные в андроид иконки, чтоб не поназванию выбирать?
Почему при задании ид группы при добавлении пункта через java указал 2?
Решил задачу!!!!
в методе onPrepareOptionsMenu просто инициализируем переменную, а в другом методе делаем с ней что хотим, и потом этот метод обрабатываем слушателем чек бокса.
пример:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
mail = menu.findItem(R.id.mail);
и т.д.}
public void someMethod(View v){
if(showItem.isChecked())
mail.setVisible(true);
else
mail.setVisible(false);
}
подкажите пожалуйста как показать список всех доступных значений параметра тэга? (напрмер списочек "if room", " never", "always", "withText"). не могу найти этот хоткей....
+Социопат Лаврентий Ctrl + пробел
почему-то перестает работать кнопка меню за пределами экрана при нажатии на нее при снятом флажке чекбокса.
у меня вместе app:showAsAction="ifRoom"/>
пишется
android:showAsAction="ifRoom"/>(если пишу app, зачеркивается красном)
на макете показывает меню в ActionBar а при запуске не показывает
в чем проблема???
подскажите пожалуйста об этом стоке:
menu.setGroupVisible(R.id.group1,ch1.isChecked());
Если с помощью menu.add добавить пункт меню, то перестает работать checkBox на эту группу.
Вот такой вариант решения ДЗ: в MainActivity объявляем Menu mainMenu;
в методе onPrepareOptionsMenu сохраняем ссылку на наше меню в эту переменную ( mainMenu = menu;) и затем вешаем слушатели на наши чек боксы по методике из предыдущих уроков, где вызываем метод onPrepareOptionsMenu:
checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onPrepareOptionsMenu(mainMenu);
}
});
твой метод не работает
Отправь свой код, если не трудно, на max.naidovich@gmail.com, я завтра вечером гляну в чем разница, а то у меня работало...
отправил код, вместо mainMenu - у меня myMenu. Проблема в том что все работает, но пункты меню не обновляются сразу, а только при обращении к меню...
Может из-за того что у меня на телефоне Андроид 17, поэтому не обновляется сразу.
Хороший способ, лаконично.
Сделал, все работает. Только лучше задавать значение mainMenu не в onPrepareOptionsMenu, а в onCreateOptionsMenu, чтобы это значение задавалось один раз при создании меню
Когда я инициализировал переменные чекбоксов в методе онкриейт, то приложение при старте выдавало ошибку и закрывалось.. потом проинициализировал переменные в методе онпрепередменю и заработало..
очень медленно выходят новые уроки для Android Studio. Жду как на иголках новых уроков.
самое понятное и логичное в программировании для андроид это устройство xml файлов, а вот сам java код... прям такая муть сложная... аж мозг коротит
Что-то народ разные ответы даёт на Д.З)Может,если Вам не трудно,подскажите хотя бы в каком направлении искать решение?)))Я так понял,нужно методы скрытия пунктов вставить в метод,который всегда работает?В
onCreateOptionsMenu вставлял-не срабатывает(.Остался OnCreate.
Или же свой метод создать,но какой?))В уроке же подсказка есть,
вы же сами сказали))Где только?..не нашёл пока.Про обработку чекбокса ещё уроков не было))Need Help!)))
Сделал :))) Если ком у то понадобится помощь, пишите в личку, скину код рабочий.
спс за отличные уроки, уже неделю 24/7 сижу за ними, черепашьими шагами уверенно продвигаюсь. заменил 5 строчек с [29 по 36] включительно на 8:45 сек на следующую строку
menu.findItem ( R.id.action_mail ).setVisible ( chb2.isChecked() );
по поводу ДЗ вопросик, чтобы статус видимости компонентов менялся в момент ЧЁКАНИЯ а не при вызове метода onPrepOptnMnu предлагаю в онкрейте на чекбоксы повесить слушателя в котором и будет происходить процесс изменения статуса setVisible, но доступ к обьектам ItemMenu и Group осуществляется через экземпляр оьекта Menu, Как выковырять его(экземпляр Menu) непосредственно напрямую, я схалтурил обьявив внешнее поле обьекта MainActivity , типа Menu myMenu и через вызов метода onPrepareOptionsMenu(Menu menu) при вызове которого в него передаётся экземпляр Menu menu там же и инициализировал внешнюю ссылку на тип Menu. Как можно ещё выковырять обьект menu?
Здравствуйте. а как менять отступ иконки от названия пункта?
Наверное, только путем кастомизации
Сделал через группу, но все равно надо нажимать на меню, чтобы исчез конверт, что делаю не так?
в коде все в порядке но когда запускаю на реальном устройстве пишет в приложении произошла ошибка. как только закоментил метод онпрепарменю все запустилось, что не так с методом?
Дима Макаренко
я наверно догадываюсь в чем у тебя проблема. Но перед тем как прочитать мой ответ выставь "брейкпоинт" в начале этого метода и в режиме debug пройди шаг за шагом чтобы посмотреть в каком месте приложение падает.
Есть второй способ: возьми весь код внутри твоего проблемного метода в блок try/catch и ты отловишь ексепшен. В выводе об ошибки кликни на ссылку на строку кода где произошла ошибка и ты наврно сам все поймешь.
А ошибка твоя скорее всего неправильно запросил объект Menu:
правильно - MenuItem menuItem1 = menu.findItem(R.id.action_menu_item1);
обрати внимание - здесь не как обычную вьюшку достаем методом (MenuItem ) findViewById(R.id.action_menu_item1) здесь надо вызывать метод findItem из объекта menu
В классе MainActivity объявляем:
Menu menuGlobal;
В методе
public boolean onCreateOptionsMenu(Menu menu)
пишем
menuGlobal = menu;
в onCreate:
chb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
// проверяем, какой чек-бокс
if (compoundButton.getId()==R.id.chb1) {
// на всякий случай проверим menuGlobal,
// вдруг onCreateOptionsMenu еще не вызывался
if (menuGlobal != null) {
MenuItem item = menuGlobal.findItem(R.id.action_mail);
// boolean b - чекнутость chb1
// ее нам дает метод onCheckedChanged
item.setVisible(b);
}
}
}
});
Код рабочий
И вот еще:
В onPrepareOptionsMenu можно написать короче,
без if-else:
action_mail.setVisible (chb2.isChecked ());
+GrafAMOR рабочее решение
tak rabotayet no tak pisat ne tak xorosho....eto anonimnie class-i prosto lutshe soztad novi class implementirovat tot interface v nyom sozdat construktor, patomv oncreate-e sozdat object etovo classa i v argumente dat evo znachenie
У меня вопрос по поводу среды разработки. В ролике на превью макете файла "menu_main.xml" открыто меню, и хорошо видны изменения. У меня же это меню закрыто.
Как можно его открыть, чтобы заранее наблюдать все изменения?
Нажмите Preview с правого края
он не это спрашивал, а говорил что в Preview у него меню в закрытый и открытым так как на видео он не может сделать.
та же проблема
ухххх у меня пригорело с меню, когда ставлю ifRoom то сверху появляется только одна картинка, а 2 как бы накладывается на нее или вообще не отображается я хз, а вот если поставить отображение always, тогда все четко.
как вы себе такие разделители сделали?) впервые раз вижу
Не нашел решения для домашнего задания, прошу помощи читал комментарии ответы непонятные где что создать не понял. Заранее всем благодарен.
Тут в свитче, есть удобный параметр item. Удобен он тем, что можно сделать case 4: case 5: case 100500: item.setCheked(! Ischecked());
Получится, элегантное чеканье, именно того пункта, который был нажат.
А вот, например я пытался изменить текст одного из множества TextView. Но там в свитч передается объект (?!) View... То есть это может быть и кнопка и и все что угодно, и не у всех есть свойство текста. Но, я же беру ответственность на себя, и определяю строгие рамки что менять цвет текста надо только если нажаты case textview1: case textview2: case textview3: case textview4: .... Но ява, не дает возможности это сделать, например так view.SetTextColor();. Или я еще не знаю о такой возможности. Приходится городить вот такое TextView tv = (TextView) view; . То есть преобразовывать view в текст вью. Можно ли как-то избавиться от такого преобразования?
Как озвучил вопрос, так сразу нашел ответ. Необходимо преобразование типов, что я и пытался сделать. Но тут есть хитрость, что весь приведенный тип надо еще брать в скобки. Получается вот так ((TextView) view).SetTextCo.... Необычная конструкция. для меня. А я уже было решил, что хочу невозможного :)))
Можно было поставить "!" перед chkb1.isChecked() , чтобы было так, как изначально задумано.
menu.setGroupVisible(group1,!(chkb1.isChecked()));
Друзья, не работает menu.setGroupVisible(R.id.group1, chk1.isChecked());выдает java.lang.NullPointerException
кто знает в чем причина, отпишитесь пожалуйста
АААА, как же это было сложно, и какое простое решение на самом деле.....
На Котлине еще проще:
В onCreateOptionsMenu вставить строку:
checkBox2.setOnCheckedListener { _, _ -> invalidateOptionsMenu () }
При создании данного урока в AnSt 2.3, приложение закрывается на устройстве с ошибкой. "В приложении произошла ошибка, ОК". Хотя в самом коде ничего не подчёркнуто...
ищите ошибку в консоли android studio
Если задокументировать данные строки в main.java:
/*@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem action_mail = menu.findItem(R.id.action_mail);
if (chb2.isChecked()) {
action_mail.setVisible(true);
} else {
action_mail.setVisible(false);
}
menu.setGroupVisible(R.id.group1,chb1.isChecked());
return super.onPrepareOptionsMenu(menu);
}*/
То ошибка пропадает и приложение начинает работать, но соответственно не отрабатываются команды группы.
А ещё внизу консольной полоски, есть пункт 4.Run есть ошибка:
"Error while executing: am startservice com.example.envy.les1/com.android.tools.fd.runtime.InstantRunService
Starting service: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=com.example.envy.les1/com.android.tools.fd.runtime.InstantRunService }
Error: Not found; no service started." - что это означает?
Спасибо.
О мой мозг )))
Спасибо! Хорошие видео-уроки. Вот такой код "menu.findItem(R.id.action_item1).setVisible(chb2.isChecked());" скрывает/отображает пункт меню.
Подскажите как выполнить домашнее задание из урока
+Евгений Стрельцов
@Override
public boolean onCreateOptionsMenu(final Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);
checkBox2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
MenuItem menuItem = menu.findItem(R.id.action_mail);
if (checkBox2.isChecked()) menuItem.setVisible(true);
else { menuItem.setVisible(false); }
}
});
Да, работает. Спасибо:)
а как изменить размер пунктов меню чтобы не занимали пол экрана, а в длину текста?
сократите текст
как называется музыка в конце ролика?
Библиотека музыки UA-cam, "Venice Beach"
В моей версии android studio (1.5.1) ваш код не отображает меню, если удалить вот эти строчки
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Перезалейте, пожалуйста новые файлы - по вашему коду дебажить уже не получается(
+Игорь Тюльканов я просто сменил тему в AndroidManifest.xml
было: android:theme="@style/AppTheme.NoActionBar"
стало: android:theme="@style/AppTheme"
Это если в эмуляторе не видно.
А если в превью не видно, то соответственно, достаточно выбрать из списка другую тему, с отображением ActionBar. (на панели, там же где и версия API)
+Игорь Тюльканов В AS 1.5.1 меню не отображается в режиме просмотра дизайна, как это исправить?
Эта особенность есть не только у меня ru.stackoverflow.com/questions/428445/android-studio-%D0%BD%D0%B5-%D0%BF%D0%BE%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D0%B5%D1%82-menu
+Victor IT Не видно именно в дизайнере, в эмуляторе порядок.
+Maxim Ka забил на этот момент. Очевидно ошибки в самом дизайнере. Когда нужно поработать с меню, перехожу непосредственно к menu_main.xml, а там выбираю тему HOLO.LIGHT. Вот там уже меню себя ведет нормально.
+Maxim Ka сегодня ещё раз столкнулся с этими проблемами рендеринга, когда баловался с темами.
До конца толком не разобрался, но там есть зависимость от того какая тема явно указана в файле манифеста и в файлах стилей, в styles.xml(v21) тоже следует заглянуть.
В итоге что сделал: тупо создал новый пустой проект и сравнил все эти файлы между собой. Из "чистого" проекта подглядел, откуда там ноги у "тем" растут и вернул всё на свои места. В итоге дизайнер нормально начал отрабатывать объявленную в манифесте тему, да и другие тоже.
Также и build.graddle стоит сравнить с "чистым" проектом.
Для отчаявшихся :
@Override
public boolean onPrepareOptionsMenu(final Menu menu) {
menu.setGroupVisible(R.id.group1,checkBox.isChecked());
checkBox2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MenuItem itemMail = menu.findItem(R.id.action_mail);
if (checkBox2.isChecked()){itemMail.setVisible(true); }else itemMail.setVisible(false);
}
});
return super.onPrepareOptionsMenu(menu);
}
Помог пост Алексея Алексеева
В обработчик онклик для чекбокса нужно добавить вызов метода onPrepareOptionsMenu(myMenu);
Создаем глобальную переменную myMenu, инициализируем в методе onCreateOptionsMenu(Menu menu)
Итого:
View.OnClickListener chbClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.checkBox2:
onPrepareOptionsMenu(myMenu);
break;
}
}
};
chb2.setOnClickListener(chbClick);
И (ключевой момент myMenu=menu;):
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
myMenu=menu;//СУПЕР ПОДСКАЗКА от Алексея
menu.add(2,4,4, "item4").setCheckable(true);
return true;
}
товарищи! начиная писав код, не забывайте сразу же следовать конвенции по написанию кода(см. офиц. сайт), правильное название переменных с суфиксами и т.д., иначе потом будет горе!
получилось вот так:
в MainActivity объявляем:
MenuItem mail;
В OnCreate добавляем слушателя смены флажка:
checkbox2.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mail.setVisible (checkbox2.isChecked ());
}
});
}
где найти эти иконки?
Віктор Лабінський www.fandroid.info/poleznye-ssylki-i-resursy-android-razrabotchika/
у всех так с боку показывает изменения в меню у меня такого нету просто
Денис Шахов Попробуйте снизить API Level для рендеринга в окне Preview
+Вячеслав Жуков это я знаю я имел ввиду что окно preview которое находится в папке с layout menu там нет окна предпросмотра, там где обычный activity_main layout там есть все
Денис Шахов Если окна Preview нет вовсе, Вы можете открыть его через View - Tool Windows - Preview или щелкнув на кнопке Preview на правой боковой панели редактора. Скорее всего, окно просто скрыто.
+Вячеслав Жуков отдуши спасибо за помощь, это то, что нужно ))
Ну в баню это, я три часа сидел, пытался сделать дз. НЕ ПОЛУЧАЕТСЯ!!! Всё Сотню раз перепроверил, переписовал из коментов. Но нет! Запускаю и у меня вылетает приложение! Если что я не на эмуляторе а на реальном устройстве
При вылете приложения, если устройство подключено к среде разработки, в LogCat можно увидеть описание ошибки
Хорошо постараюсь разобраться.Спасибо
+ERDZe | Old Channel +Maxim Ka разобрался)
В классе MainActivity объявляем:
Menu menuGlobal;
В методе onCreateOptionsMenu(Menu menu)
menuGlobal = menu;
В методе onCreateOptionsMenu:
final MenuItem action_mail= menu.findItem(R.id.action_mail);
chb2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (chb2.isChecked()) {
action_mail.setVisible(true);
} else {
action_mail.setVisible(false);
}
}
});
и все)
+Виталий Мордак а можно обвернуть нужный пункт меню в групу и одной строчкой его обозначить).
проще всего вроде как
Может и проще, но я нашел для себя такое решение)
+Виталий Мордак спасибо, через твой код разобрался =)
+Виталий Мордак Спасибо, а то уже всю голову себе сломал)
+Виталий Мордак Всё ещё проще, в методе onPrepareOptionsMenu одной строкой:
menu.findItem(R.id.action_mail).setVisible(chb2.isChecked());
Самый эффективный вариант ДЗ :
public boolean onPrepareOptionsMenu(Menu menu) {
item1 = menu.findItem(R.id.action1);
item1.setVisible(checkBox2.isChecked());
menu.setGroupVisible(R.id.group1, checkBox.isChecked());
return super.onPrepareOptionsMenu(menu);
}
Просто добавляем item1.setVisible(checkBox2.isChecked()); в метод onPrepareOptionsMenu :)
Вариант эффективный, но неправильный:)
Вешаем на чекбокс слушателя:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
menuItem = menu.findItem(R.id.action_item);
checkBox.setOnClickListener(v ->
menuItem.setVisible(((CheckBox) v).isChecked()));
return super.onCreateOptionsMenu(menu);
}
Хочу предостеречь людей из 2020 года, кто сюда забрел и пытается сделать домашнее задание и в ответах наткнулся на вариант с invalidateOptionsMenu(); Проблема в том что метод invalidateOptionsMenu(); вызывает не только метод onPrepareOptionsMenu, но и метод onCreateOptionsMenu, т.е. меню пересоздается целиком. Это легко проверить, ведь будет теряться флаг на меню Item4, который вы до этого поставили. Поэтому можно отдельно вызывать только метод перерисовки меню onPrepareOptionsMenu(), ему на вход надо дать "меню", его можно предварительно сохранить в глобальную переменную.
Вариант ДЗ с учетом навыков, полученных на предыдущих уроках:
Создаем глобальную переменную MenuItem action_mail;
Добавляем обработчик для второго чек-бокса в метод OnCreate:
chb2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (chb2.isChecked()) {
action_mail.setVisible(true);
} else {
action_mail.setVisible(false);
}
}
});
в таком случае переменная action_mail будет равна null
Всё перепробовал пересмотрел пару сотен комментариев здесь ничего не работало. Конвертик не исчезал по щелчку на checkbox.
Сработало только когда пункт меню с конвертиком обернул в группу, как он тут говорит.
И только в этом разрезе вот эта байда работает корректно:
public boolean onCreateOptionsMenu(final Menu menu) {
chd2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
menu.setGroupVisible(R.id.group2, chd2.isChecked());
}
});
}
помогите с ДЗ ничего не могу сделать((((
Подсказка как сделать ДЗ)
Создаете в onCreate обработчик onClickListener с onClick в нем switch с определением ид элемента на который нажали и вызовом методов clickChkVisibleGroup и clickChkVisibleItem. Далее цепляете в этом методе этот onClickListener к элементам чекбоксам.
Создаете глобальную переменную Menu myMenu; в событии onCreateOptionsMenu загоняете в эту переменную ссылку на меню myMenu = menu.
Метод void на вкл-выкл группы:
public void clickChkVisibleGroup(){
myMenu.setGroupVisible(R.id.group1, chb1.isChecked());
onPrepareOptionsMenu(myMenu);
}
Метод на вкл-выкл элемента:
public void clickChkVisibleItem(){
MenuItem action_mail = myMenu.findItem(R.id.action_mail);
action_mail.setVisible(chb2.isChecked());
onPrepareOptionsMenu(myMenu);
}
Как все это сделать рассказано в предыдущих уроках! Спасибо за видеоуроки автору!
Алексей Горшков
Вообще, я так смотрю подход когда после какого-то действия надо "перерисовать" вьюшку или иной элемент - очень частый. Только диву даешься как андроид это делает у тебя на глазах с такой скоростью что ты даже не замечаешь малейшего мигания.
в ДЗ фактически мы делаем очередные слушатели по событию (нажали на чекбокс), в нем мы меняем как выглядеть должна менюшка (объект Menu который мы вынесли в поле класса) и следом команда "перерисовать" менюшку (onPrepareOptionsMenu(menu);)
Алексей Горшков Мы весь код написали в onPrepareOptionsMenu.Чек-боксы у нас уже вынесены в поля класса. В onCreateOptionsMenu достаточно повесить OnCheckedChange лисенер на чек-бокс, который бы просто вызывал метод onPrepareOptionsMenu постоянно когда он выбирается. По сути мы будем переподготавливать меню каждый раз при нажатии чек-бокса, но для небольших меню это должно подойти.
+Алексей Горшков зачем пихать myMenu в onPrepareOptionsMenu()?
+Вячеслав Жуков А можете показать код OnCheckedChange который вызывает onPrepareOptionsMenu ?
+Костя Семенов Я вот так написал, вроде работает
public boolean onCreateOptionsMenu(final Menu menu){
getMenuInflater().inflate(R.menu.menu_main, menu);
chb1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
invalidateOptionsMenu();
}
});
return true;
}
во как
check1.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
invalidateOptionsMenu ( );
}
});
check2.setOnClickListener(new View.OnClickListener(){
public void onClick(View view){
invalidateOptionsMenu ( );
}
});
I have realized this task in OnCreate method like below :
CheckBox ch01,ch02;
MenuItem mail ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ch01 = (CheckBox) findViewById(R.id.ch01);
ch02 = (CheckBox) findViewById(R.id.ch02);
View.OnClickListener click = new View.OnClickListener() {
@Override
public void onClick(View view) {
invalidateOptionsMenu();
}
};
ch02.setOnClickListener(click);
}
@Override
protected boolean onPrepareOptionsPanel(@Nullable View view, @NonNull Menu menu) {
if (ch01.isChecked()){
menu.setGroupVisible(R.id.group1,false);
}else {
menu.setGroupVisible(R.id.group1,true);
}
mail = menu.findItem(R.id.action_mail);
if(ch02.isChecked()){
mail.setVisible(false);
}
else {
mail.setVisible(true);
}
Если ты смотришь этот ролик и ты новичек, игнорируй дз. Потому что навыков данных в этом уроке не хватит чтобы сделать его. А если хочешь выполнить придется самому гуглить определенную информацию.
Вот рабочее решение, без сторонних методов, о которых в видео речи не шло.
public boolean onPrepareOptionsMenu(Menu menu) {
final MenuItem action_settings = menu.findItem(R.id.action_settings);
chb2.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick (View view){
if (chb2.isChecked()) {
action_settings.setVisible(true);
} else if (!chb2.isChecked()) {
action_settings.setVisible(false);
}
}
});
menu.setGroupVisible(R.id.group1, chb1.isChecked());
return super.onPrepareOptionsMenu(menu);
}
спасибо, работает!!
с точки зрения задания да можно так решить, но на мой взгляд решение не лучшее, ведь "лисенер" будет создаваться столько раз сколько будет перерисовываться меню, зачем? Я новичок и не уверен, что это не будет отъедать лишнюю память, про сроки жизни этих лисенеров пока ничего не говорили, вдруг они накапливаются и после того как вы 100 раз снимете и поставите галочку на группе телефон съест всю свободную память. Его можно создать всего 1 раз в момент инициализации MainActivity.
Ура;) Я первый)
P.S не когда не был первым ;(
public class MainActivity extends AppCompatActivity {
CheckBox chb1 , chb2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chb1 = (CheckBox) findViewById(R.id.chb1);
chb2 = (CheckBox) findViewById(R.id.chb2);
chb2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
refresh();
}
});
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item5 = menu.findItem(R.id.item5);
if (chb2.isChecked()){
item5.setVisible(true);
}else {
item5.setVisible(false);
}
menu.setGroupVisible(R.id.group1, chb1.isChecked());
return super.onPrepareOptionsMenu(menu);
}
public void refresh(){
if (Build.VERSION.SDK_INT >= 11) {
invalidateOptionsMenu();
} else {
supportInvalidateOptionsMenu();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id){
case R.id.item1:
Toast.makeText(MainActivity.this, "ITEM 1", Toast.LENGTH_LONG).show();
break;
case R.id.item2:
Toast.makeText(MainActivity.this, "ITEM 2", Toast.LENGTH_LONG).show();
break;
case R.id.item3:
Toast.makeText(MainActivity.this, "ITEM 3", Toast.LENGTH_LONG).show();
break;
case R.id.item4:
Toast.makeText(MainActivity.this, "ITEM 4", Toast.LENGTH_LONG).show();
break;
case R.id.item5:
Toast.makeText(MainActivity.this, "ITEM 5", Toast.LENGTH_LONG).show();
break;
}
return true;
}
}
У меня получилось!)))
@Override
public boolean onCreateOptionsMenu(final Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);
checkBox2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View view)
{
MenuItem menuItem = menu.findItem(R.id.action_mail);
if (checkBox2.isChecked()) menuItem.setVisible(true);
else { menuItem.setVisible(false); }
}
});
public class MainActivity extends AppCompatActivity {
TextView textView;
CheckBox chB1;
CheckBox chB2;
View.OnClickListener listener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTitle("CheckBox");
textView = (TextView) findViewById(R.id.iD_textView);
chB1 = (CheckBox) findViewById(R.id.iD_chB1);
chB2 = (CheckBox) findViewById(R.id.iD_chB2);
listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
invalidateOptionsMenu();
}
};
chB1.setOnClickListener(listener);
chB2.setOnClickListener(listener);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.setGroupVisible(R.id.iD_group1, chB1.isChecked());
menu.setGroupVisible(R.id.iD_group2, chB2.isChecked());
return super.onPrepareOptionsMenu(menu);
}
supportInvalidateOptionsMenu(); //Перестроить меню
Не понимаю всех вас, какой смысл просить код для ДЗ? Вы что с ним, в школу пойдете учителю информатики за пятерку предъявлять? Эти ДЗ Виталий дает, чтобы вы пробовали *САМИ*, пытались что-то делать, учились на практике
Добрый день! Целый час думал над домашним заданием. Смотрел комменты. Что-то может не увидел. Но предложенные варианты приводили к использованиям новых методов или переменных. Пробовал вешать слушателя метод onCreate. Но все это не приводило к результатам. Потом попробовал повешать слушателя в метод onPrepareOptionsMenu и все заработало:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem action_mail = menu.findItem(R.id.action_mail);
chb2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
action_mail.setVisible(chb2.isChecked());
}
});
menu.setGroupVisible(R.id.group1,chb1.isChecked());
return super.onPrepareOptionsMenu(menu);
}
Механизма работы я так и не понял. Ведь метод PrepareOptionsMenu должен срабатывать когда нажимают на меню. Почему срабатывает слушатель внутри него для меня загадка. Прошу спецов разьяснить.
Если ты смотришь этот ролик и ты новичек, игнорируй дз. Потому что навыков данных в этом уроке не хватит чтобы сделать его. А если хочешь выполнить придется самому гуглить определенную информацию.