Как получить позицию элемента из PopupMenu в пользовательском ListView

Вот проблема: у меня есть пользовательский ArrayAdapter (overriden getView). Каждый предмет имеет

  • 2 ImageView
  • 2 EditText

Один из этих ImageView доступен для кликов и включает PopupMenu, поэтому у меня есть небольшой PopupMenu для каждого элемента списка. Теперь для этого меню мне нужны некоторые параметры из элемента, который привязан. Итак, как передать информацию (например, позицию) методу, вызванному из голоса PopupMenu? Присоединение xml-файлов.

item_list.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="5dp" android:paddingTop="5dp" > <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="6dip" android:contentDescription="TODO" android:src="@drawable/ic_launcher" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:id="@+id/firstLine" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:maxHeight="60dp" android:text="Title" android:textSize="16sp" /> <ImageView android:id="@+id/imageView1" android:layout_width="25dp" android:layout_height="25dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:contentDescription="TODO" android:onClick="showMenu" android:src="@drawable/abc_ic_menu_moreoverflow_normal_holo_light" /> <TextView android:id="@+id/secondLine" android:layout_width="fill_parent" android:layout_height="26dip" android:layout_alignParentLeft="true" android:layout_below="@+id/firstLine" android:ellipsize="marquee" android:singleLine="true" android:text="Author" android:textSize="12sp" /> </RelativeLayout> </LinearLayout> 

menu_item.xml

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/preview" android:onClick="preview" android:title="@string/preview"/> <item android:id="@+id/download" android:onClick="download" android:title="@string/download"/> </menu> 

CustomArrayAdapter.java

 public class CustomArrayAdapter extends ArrayAdapter<Custom>{ private final Context context; private final List<Custom> values; private final int resource; private final ImageCache imgCache = new ImageCache(); public CustomArrayAdapter(Context context, int resource, List<Custom> values) { super(context, resource, values); this.context = context; this.values = values; this.resource = resource; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh; Custom Custom = values.get(position); if (convertView == null) { vh = new ViewHolder(); LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(resource, parent, false); vh.title = (TextView) convertView.findViewById(R.id.firstLine); vh.author = (TextView) convertView.findViewById(R.id.secondLine); vh.albumImage = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(vh); } else { vh = (ViewHolder)convertView.getTag(); } vh.requestedCustom = Custom; vh.title.setText(Custom.getTitle()); vh.author.setText(Custom.getAuthor()); String imgUrl = Custom.getImgUrl(); if (imgUrl != null) { imgCache.getImage(Custom, vh); } else { vh.albumImage.setImageResource(R.drawable.no_album); } return convertView; } // This is a ViewHolder that helps in the view recycling public static class ViewHolder { public Custom requestedCustom; public TextView title; public TextView author; public ImageView albumImage; } } 

Для методов «предварительного просмотра» и «загрузки» требуются параметры из связанного элемента списка, и я не знаю, как их получить. Еще раз спасибо.

ИЗМЕНИТЬ 1

Кажется, что вместо контекстного меню нужно использовать (правильно?), Но я хотел бы привязать его к каждому элементу как своеобразное всплывающее меню, которое появляется. Итак, как я могу это достичь? Для тех, кто не понимает, что я хочу (из-за моего худшего английского): приложение Google Play, всплывающее меню, которое позволяет выбирать между «Install» или «Добавить в whishlist».

Вы можете создать свой класс слушателя следующим образом:

 class myClickListener implements OnClickListener, OnMenuItemClickListener { long id; public myClickListener(long id) { this.id = id; } @Override public void onClick(View v) { PopupMenu popup = new PopupMenu(appContext, v); popup.setOnMenuItemClickListener(this); MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.menu_item, popup.getMenu()); popup.show(); } @Override public boolean onMenuItemClick(MenuItem arg0) { Toast.makeText(appContext, "ID of selected row : " + id , Toast.LENGTH_SHORT).show(); return false; } } 

И добавьте этот прослушиватель в ваше изображение в своем переопределенном методе getView класса адаптера:

 imageView.setOnClickListener(new myClickListener(getItemId(position))); 

Просто нам нужно установить тег кнопок в качестве его положения, а onClick на PopupButton вам нужно получить представление:

 button.setTag(position); //may be you can call this on getview method of list view button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { int position = (Integer) v.getTag(); // you will get the position } }); 

Или использование интерфейса в вашем фрагменте реализует View.OnClickListener

 private void showPopupMenu(View view) { final int position = (Integer) view.getTag(); PopupMenu popup = new PopupMenu(getActivity(), view); // Inflate our menu resource into the PopupMenu's Menu popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu()); // Set a listener so we are notified if a menu item is clicked popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem menuItem) { switch (menuItem.getItemId()) { case R.id.menu_remove: System.out.println(position); return true; } return false; } }); // Finally show the PopupMenu popup.show(); } 

Невозможно достичь того, чего вы хотите, с помощью onClick, объявленного XML. Самый простой способ решить эту проблему с вашей реальной реализацией:

  • Добавьте реального зрителя в свой ImageView после его раздувания. Внутри адаптера.
  • Слушатель должен быть настраиваемым классом, реализующим интерфейс OnClickListener
  • Вы также должны предоставить вашему слушателю дополнительный член данных: позицию (строку), содержащую ImageView.
  • Когда слушатель активирован, он должен будет вызвать обратный вызов активности, которая отобразит Диалог, тогда слушатель передаст позицию.

Вот как я это сделал:

  1. Вместо хранения ViewHolder в тегах convertView в методе getView (int position, View convertView, ViewGroup parent) в CustomArrayAdapter я сохранил сам пользовательский объект. Я даже не использовал держатель.

     convertView.setTag(getItem(position)); 

    (Если вам действительно нужно хранить ViewHolder, вы можете использовать setTag (int key, Object tag) для хранения нескольких тегов)

  2. Когда showMenu (View view) вызывается ImageView, я использую view.getParent () для получения родительского LinearLayout текущего выбранного представления, в котором у меня есть свой пользовательский объект.

     View parent = (View) view.getParent(); 
  3. Outside showMenu () Я определил публичное свойство для хранения выбранного в данный момент элемента следующим образом:

     public static Custom mSelectedItem; 
  4. Внутри showMenu () я установил mSelectedItem в getTag () родительского LinearLayout с шага 2.

     mSelectedItem = (Custom) parent.getTag(); 
  5. Наконец, в методе переопределения onMenuItemClick (MenuItem menuItem) я использую mSelectedItem для определения текущего выбранного элемента.

     Custom custom = mSelectedItem;