Intereting Posts
Как «уничтожить» несколько действий Android одновременно Что хорошего setAudioEncodingBitRate для записи голоса Динамическая высота списка андроидов Закладка пунктов меню в панели действий sherlock CollapsingToolbarLayout не отображает заголовок Как фильтровать определенные приложения для намерения ACTION_SEND (и устанавливать другой текст для каждого приложения) Андроид локальное разрешение Androidmanifest SMS READ Самый верхний просмотр событий ласточек, поскольку перекрытие Ошибка приложения при создании стопки Eclipse не генерирует файл apk для любого приложения, разработанного в нем? Что такое файл boot.img в android? Crosswalk Cordova – js alert показывает символы блока на китайском интерфейсе android Должен ли я вызвать super () при переопределении конструктора AsyncTask? Цвет значков панели состояния Android Как мне организовать контроль источника для проектов Android, включая библиотеки?

Определение вида, выбранного в ContextMenu (Android)

В Android onContextItemSelected имеет один аргумент MenuItem и поэтому неясно, как идентифицировать выбранное представление. MenuItem.getMenuInfo предоставляет доступ к Contextmenu.ContextMenuInfo , но, хотя оба известных подкласса обеспечивают доступ к целевому представлению, на интерфейсе не появляется аксессор.

Один из вариантов заключается в том, чтобы сохранить View представленное в onCreateContextMenu в переменной частного класса, которая полагается на onCreateContextMenu не будет снова вызвана в активности перед onContextItemSelected . Другим является использование идентификатора представления для аргумента itemId для ContextMenu.add . Если мы это сделаем, нам нужно будет определить вариант, выбранный из контекстного меню, используя его (возможно, интернационализированное) название.

Каков наилучший метод идентификации View выбранного в onContextSelected ?

Не существует такой концепции, как «определение выбранного вида» для любого меню или контекстных меню в Android. Следовательно, на ваш вопрос довольно сложно ответить. Итак, я сделаю некоторые догадки.

Если, выбрав «Выбранный вид», вы имеете в виду, какой выбор меню был выбран, то есть getItemId() в MenuItem который передается onOptionsItemSelected() или onContextItemSelected() .

Если «идентифицировать вид выбранный» означает, какая строка в ListView была одной длинной, чтобы вызвать контекстное меню, getMenuInfo() (вызываемый в MenuItem ) в AdapterView.AdapterContextMenuInfo , затем используйте либо id либо Значения position в зависимости от вашего адаптера. См. Здесь пример проекта, который использует эту технику.

Если, «идентифицировав View selected», вы имеете в виду, что у вас есть несколько контекстных меню не ListView в действии, я бы не использовал эту технику пользовательского интерфейса.

Весь смысл контекстного меню заключается в том, что он связан с отдельным основным представлением, и это явно ограничение по дизайну в Android, что ассоциация теряется в обратном вызове 'onContextItemSelected'. Включение длинного касания в любом представлении достаточного размера представляется вполне разумным в качестве альтернативы щелчку правой кнопки мыши.

Как и другие должности, рекомендуется в некоторых контекстах:

 AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); 

Является подходящим, и targetView является полезной контрольной точкой.

Другой способ заключается в подклассе представления и переопределении 'getContextMenuInfo' для предоставления ссылки на представление. Например, простой TextView:

 Пакет ...;

 Открытый класс TextViewWithContext расширяет TextView {
     TextViewContextMenuInfo _contextMenuInfo = null;

     Public TextViewWithContext (контекст контекста) {
         супер (контекст);
         _contextMenuInfo = новый TextViewContextMenuInfo (this);
     }

     Public TextViewWithContext (контекст контекста, AttributeSet attrs) {
         Супер (контекст, attrs);
         _contextMenuInfo = новый TextViewContextMenuInfo (this);
     }   

     Protected ContextMenuInfo getContextMenuInfo () {
         Return _contextMenuInfo;
     }

     Public boolean isContextView (ContextMenuInfo menuInfo) {
         Return menuInfo == (ContextMenuInfo) _contextMenuInfo;
     }

     Защищенный класс TextViewContextMenuInfo реализует ContextMenuInfo {
         Protected TextView _textView = null;

         Защищенный TextViewContextMenuInfo (TextView textView) {
             _textView = textView;
         }
     }
 }

 ...
     @Override
     Public boolean onContextItemSelected (элемент MenuItem) {   

         ContextMenuInfo menuInfo = item.getMenuInfo ();

         If (textViewWithContext.isContextView (menuInfo) {
             ...
         }
     }

Наконец, было бы более полезно, если базовому классу View был назначен объект ContextInfo с обратной ссылкой на представление, а не null, как в настоящее время.

Class TestActivity расширяет действие {

 // create temp item here private ImageView tmpImageView = null; 

 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){ super.onCreateContextMenu(menu, v, menuInfo); // initialize temp item mCurrentStatusImage = (ImageView) v.findViewById(R.id.rule_status); } public boolean onContextItemSelected(MenuItem item) { switch (item.getItemId()) { case ENABLE_ID: // use temp item tmpImageView.setImageResource(android.R.drawable.presence_online); return super.onContextItemSelected(item); case DISABLE_ID: // use temp item tmpImageView.setImageResource(android.R.drawable.presence_invisible); return super.onContextItemSelected(item); default: return super.onContextItemSelected(item); } 

Я установил аналогичную проблему, установив идентификатор groupID для MenuItem, на основе которого отправлен элемент, например:

  textview.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) { menu.setHeaderTitle("Context Menu"); menu.add(R.id.whateverviewclicked, RENAME_MENU_ITEM, 0, "Rename"); menu.add(R.id.whateverviewclicked, DELETE_MENU_ITEM, 1, "Delete"); } }); 

Это позволит вам получить идентификатор groupID в onContextItemSelected:

 public boolean onContextItemSelected(MenuItem aItem) { int selectedViewID = aItem.getGroupId(); int selectedItem = aItem.getItemId(); }; 

Вам не нужно использовать идентификатор ресурса – вы можете использовать любой, который хотите. Работает на меня!

Если вы прикрепляете ContextMenus к нескольким представлениям, которые НЕ находятся в ListView (то есть нет адаптера, лежащего в основе представлений), и вы хотите определить, какой вид View был долго нажат для доступа к ContextMenu, может быть реализован следующий «хак». (Было бы лучше, если бы Android предоставил слушателю, который мог бы быть связан с каждым элементом).

«Хак» состоит в том, что создается частный элемент просмотра mLastViewTouched в классе, а затем добавляется следующий onTouchListener ко всем представлениям, которые могут генерировать ContextMenu:

  private View.OnTouchListener onTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { mLastViewTouched = view; // Store a handle on the last view touched. This will be used to identify the view on which the Context Menu was launched return false; // We return false since this indicates that the touch was not handled and so it is passed down the stack to be handled appropriately } }; 

Поэтому всякий раз, когда вид затрагивается, mLastViewTouched обновляется. Теперь в onContextItemSelected вы получите доступ к представлению, инициировавшему ContextMenu.

При создании своего меню в OnCreateContextMenuListener или public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) вы можете установить пользовательский MenuItem.OnMenuItemClickListener для каждого элемента:

  addPhotosBtn.setOnCreateContextMenuListener((menu, v, menuInfo) -> { getMenuInflater().inflate(R.menu.upload_image_menu, menu); int itemCount = menu.size(); for(int i = 0; i < itemCount; i++) { menu.getItem(i).setOnMenuItemClickListener(addPhotosBtnMenuItemClickListener); } }); 

Поскольку в это время у вас есть доступ к представлению, для которого вы создаете контекстное меню, вы можете плотно связать слушателя с этим представлением.