Обнаружить, что PopupMenu закрыт на уровне API 11

У меня есть это PopupMenu в моем приложении, и я хотел бы знать, когда он закрыт. С API14+ это легко сделать при добавлении прослушивателя отклонения с помощью setOnDismissListener(). Но мне нужно знать, когда PopupMenu закрывается из API11+, поэтому я не могу использовать прослушиватель и мне нужна альтернатива для прослушивателя.

Это я уже пробовал:

  • переопределить метод dismiss() PopupMenu, но он не вызывается при его закрытии.
  • используйте PopupMenu.OnMenuItemClickListener, но он не активируется, когда пользователь щелкает за пределами меню (чтобы закрыть его) или нажимает «назад».

У меня нет других идей, чтобы обнаружить, что меню было закрыто. Поэтому я надеюсь, что у кого-то есть хитрый трюк. В противном случае я не могу использовать PopupMenu...


person Veger    schedule 15.10.2012    source источник
comment
Немного хакерски, но можете ли вы установить OnFocusChangeListener из базового представления или группы просмотра? Честно говоря, я не уверен, что он сработает, но это первое, о чем я могу подумать. Кроме этого, вы можете слушать в 3 точках (menuItemClick, кнопка «Назад», onTouch of contentView), но я уверен, что должно быть что-то лучше этого.   -  person Geobits    schedule 16.10.2012
comment
@Geobits Спасибо за вашу идею (я об этом не подумал). Но использование OnFocusChangeListener, к сожалению, не работает. У меня есть только представление (на котором я рисую свой пользовательский интерфейс), и не похоже, что оно когда-либо получает фокус (или теряет) его...   -  person Veger    schedule 16.10.2012


Ответы (1)


Вы можете попробовать переопределить метод

public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing)

PopupMenu класса. Именно этот метод вызывает setOnDismissListener() внутри API 14+. Но сделать это непросто. Проблема в том, что класс com.android.internal.view.menu.MenuBuilder не включен в Android SDK, поэтому вы не сможете скомпилировать свой код, если попытаетесь импортировать этот класс.

Однако вы можете создать свою собственную «поддельную» реализацию этого класса, поместить ее в пакет com.android.internal.view.menu, создать с ней файл .jar, скопировать эту «поддельную библиотеку» в папку libs и установить область действия этой библиотеки в настройках проекта IntelliJ IDEA как "при условии". Это значит, что у классов в этом jar файле уже есть реальные устройства (что правда) и они нужны вам только для компиляции вашего кода. Основная идея здесь - ваш поддельный MenuBuilder должен быть в пути к классам для компиляции javac, но не должен быть включен в результирующий файл .apk.

Это непростое решение, но оно должно работать.

person HitOdessit    schedule 26.10.2012
comment
Спасибо за вашу идею! Думаю, это могло бы решить мою проблему. Я создал поддельную реализацию для MenuBuilder (хорошая идея!), но я не могу найти настройку области (она специфична для Maven? Я не использую Maven), не могли бы вы указать, где я должен ее найти? Кроме того, метод onCloseMenu() нельзя переопределить, по крайней мере, так кажется. Удаление аннотации @Override решает эту проблему, но я получаю предупреждение о том, что она никогда не используется. Я так понимаю не работает? Любые дополнительные подробности очень приветствуются! - person Veger; 27.10.2012
comment
После еще одного тестирования я работаю на своем устройстве API14+, но не на устройстве API11 (для которого это должно предоставить решение). Может ли быть так, что в API11 нет метода onCloseMenu(), поэтому он не вызывается? - person Veger; 27.10.2012
comment
Вы можете настроить область действия для библиотек хотя бы в IntelliJ IDEA. Я думаю, что нечто подобное должно быть возможно сделать с помощью сборок Ant или Maven, но я еще не пробовал. - person HitOdessit; 27.10.2012
comment
Я сделал такой тест: используя отражение, выведите все методы класса PopupMenu в журнал и запустите его на эмуляторе API 11 - он печатает метод onCloseMenu(). Итак, я думаю, что этот метод присутствует в версии API 11 класса PopupMenu. Я все еще думаю, что решение должно работать, если вы правильно настроите свою сборку. Главное - ваш поддельный MenuBuilder должен быть в пути к классам для компиляции javac, но не должен быть включен в результирующий .apk - person HitOdessit; 27.10.2012
comment
Я попробовал еще раз, это работает для API14, но не для API11. Когда я использовал отражение, он действительно показывает метод onCloseMenu(). Я убедился, что использую точно такие же параметры, но мой метод не вызывается... Когда я изменяю имя своего метода, оно становится видимым при отражении, поэтому я, кажется, переопределяю правильный метод (как это происходит не показаны как оригинал, так и мой метод). Я не знаю, что еще я могу попробовать использовать вашу идею... :( - person Veger; 30.10.2012
comment
Плохо, что мы не можем получить исходники API уровня 11 :( Странно, что метод onCloseMenu() представлен в API 11, но не вызывается, очень странно. Но у меня больше нет идей по этому поводу, извините - person HitOdessit; 30.10.2012