Android context menu recyclerview

brettwold / CustomAdapter.java

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

xml version = » 1.0 » encoding = » utf-8 » ?>
menu xmlns : android = » http://schemas.android.com/apk/res/android » >
item
android : id = » @+id/menu_custom_edit «
android : title = » @string/menu_custom_edit »/>
item
android : id = » @+id/menu_custom_delete «
android : title = » @string/menu_custom_delete »/>
menu >

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

public class CustomAdapter extends RecyclerView . Adapter CustomAdapter .ViewHolder > <
private List CustomObject > objects;
private OnItemSelectedListener listener;
private final boolean withContextMenu;
class ViewHolder extends RecyclerView . ViewHolder
implements View . OnClickListener , View . OnCreateContextMenuListener , PopupMenu . OnMenuItemClickListener <
@BindView ( R . id . custom_name)
TextView name;
@BindView ( R . id . custom_value)
TextView value;
ViewHolder ( View view ) <
super (view);
ButterKnife . bind( this , view);
view . setOnClickListener( this );
if (withContextMenu) <
view . setOnCreateContextMenuListener( this );
>
>
@Override
public void onClick ( View v ) <
int position = getAdapterPosition();
if (listener != null ) <
listener . onCustomerSelected(objects . get(position));
>
>
@Override
public void onCreateContextMenu ( ContextMenu menu , View v , ContextMenu . ContextMenuInfo menuInfo ) <
PopupMenu popup = new PopupMenu (v . getContext(), v);
popup . getMenuInflater() . inflate( R . menu . custom_menu, popup . getMenu());
popup . setOnMenuItemClickListener( this );
popup . show();
>
@Override
public boolean onMenuItemClick ( MenuItem item ) <
if (listener != null ) <
CustomObject object = objects . get(getAdapterPosition());
listener . onCustomerMenuAction(object, item);
>
return false ;
>
>
public CustomerAdapter ( List CustomObject > objects , OnItemSelectedListener listener , boolean withContextMenu ) <
this . listener = listener;
this . objects = objects;
this . withContextMenu = withContextMenu;
>
public interface OnItemSelectedListener <
void onSelected ( CustomObject object );
void onMenuAction ( CustomObject object , MenuItem item );
>
@Override
public CustomerAdapter . ViewHolder onCreateViewHolder ( ViewGroup parent , int viewType ) <
View v = LayoutInflater . from(parent . getContext()) . inflate( R . layout . snippet_custom_object_line, parent, false );
return new ViewHolder (v);
>
@Override
public void onBindViewHolder ( CustomAdapter . ViewHolder holder , int position ) <
CustomObject object = objects . get(position);
holder . name . setText(object . getName());
holder . value . setText(object . getValue());
>
@Override
public int getItemCount () <
return objects . size();
>
>

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

public class CustomFragment extends Fragment implements CustomAdapter . OnItemSelectedListener <
@BindView ( R . id . custom_objects)
RecyclerView objects;
private List CustomObject > objects;
@Override
public void onResume () <
super . onResume();
setupObjectList();
>
private void setupObjectList () <
objects . setLayoutManager( new LinearLayoutManager (getContext()));
CustomAdapter customAdapter = new CustomAdapter (objects, this , true );
objects . setAdapter(customAdapter);
>
@Override
public void onSelected ( CustomObject object ) <
// Do something on select
>
@Override
public void onMenuAction ( CustomObject object , MenuItem item ) <
switch (item . getItemId()) <
case R . id . menu_custom_edit :
// Add edit screen
break ;
case R . id . menu_custom_delete :
objects . remove(object);
setupObjectList();
break ;
>
>
>
Читайте также:  Android xml style attributes

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Источник

gauravat16 / ActivityName.java

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

// Import Statements
public class ActivityName extends AppCompatActivity <
private RecyclerView mRecyclerView;
private RecyclerView . Adapter mAdapter;
private RecyclerView . LayoutManager mLayoutManager;
@Override
protected void onCreate ( Bundle savedInstanceState ) <
super . onCreate(savedInstanceState);
setContentView( R . layout . activity_view_birthdays);
// Recycle View
mRecyclerView = ( RecyclerView ) findViewById( R . id . my_recycler_view);
mLayoutManager = new LinearLayoutManager (getApplicationContext());
mRecyclerView . setLayoutManager(mLayoutManager);
mAdapter = new BirthdaysListAdapter (data, this );
mRecyclerView . setAdapter(mAdapter);
>

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Источник

Как создать контекстное меню для RecyclerView

Как реализовать контекстное меню RecyclerView? по-видимому, называя registerForContextMenu(recyclerView) не работает. Я вызываю его из фрагмента. Кто-нибудь добился успеха в реализации этого?

18 ответов

привет ребята, вы не можете напрямую реализовать этот метод, как onClickListener, OnContextMenuListener etc. потому что RecycleView выходит android.вид.ViewGroup поэтому мы не можем напрямую использовать этот метод. мы можем реализовать эти методы в ViewHolder класс адаптера. мы можем использовать контекстное меню в RecycleView следующим образом

Теперь мы следуем той же процедуре, реализует контекстное меню.

Если у вас возникнут какие-либо трудности, спросите в комментарии. Гордиться androidian 🙂

Спасибо за информацию и комментарии. Мне удалось добиться ContextMenu для пользования в Recyclerview .

вот что я сделал

в Фрагмент onViewCreated метод или деятельность onCreate способ:

затем в адаптер добавить

сделать ViewHolder класс реализации OnCreateContextMenuListener

onBindViewHolder метод add OnLongClickListener на держателе.itemView для захвата позиции перед контекстным меню загружено:

затем в onViewRecycled удалите прослушиватель, чтобы не было проблем с ссылками. (может не потребоваться).

наконец, в фрагменте / Activity переопределите onContextItemSelected на

текущий ответ неверен. Вот рабочая реализация:

в вашем фрагменте (или деятельности):

и, наконец, в ViewHolder:

попробуйте это для View деталь в recycleView

вы можете использовать его с установкой данных ViewHolder элемент

Прабхакар ответ правильно, но он не объяснил, как получить данные, связанные с нажатым элементом, когда выбран пункт контекстного меню. Мы можем использовать onContextItemSelected обратного вызова, но ContextMenuInfo не имеется ( null ) в этом случае (если getContextMenuInfo() метод не переопределяется для нажатого представления). Итак, самое простое решение-добавить OnMenuItemClickListener непосредственно MenuItem .

ответ@Renaud работал для меня, но сначала требовалось несколько исправлений кода. Это похоже на то, что он опубликовал фрагменты из нескольких разных итераций своего кода. Необходимо внести следующие изменения:

  • RecyclerContextMenuInfo и RecyclerViewContextMenuInfo являются одним и тем же классом. Выберите имя и придерживайтесь его.
  • на ViewHolder необходимо реализовать View.OnLongClickListener , и не забудьте позвонить setOnLongClickListener() по элементу в конструкторе.
  • на onLongClick() слушатель getView().showContextMenu() совершенно неверно. Вы надо позвонить showContextMenuForChild() в своем ContextMenuRecyclerView , иначе ContextMenuInfo вы получаете в onCreateContextMenu() и onContextItemSelected() будет null.
Читайте также:  Андроид настройка экрана при вызове

мой отредактированный код ниже:

в свой фрагмент:

кроме того, убедитесь, что вы замените RecyclerView С ContextMenuRecyclerView в макете!

Я объединил свое решение с решением от @Hardik Shah:

в деятельности у меня есть:

в адаптере у меня есть:

во фрагменте у меня:

Я, может быть, поздно на вечеринку, но у меня есть рабочего раствора. Я сделал для него суть.

ActivityName.java

RecyclerAdapter.java

Привет, ребята, вышел с одной альтернативой, которая работает для меня. Я просто регистрирую свой itemView с registerContextMenu y конструктором ViewHolder, а также устанавливаю onLongClikcListener в то же представление. В реализации onLongClick(View v) я просто получаю щелкнутую позицию с помощью getLayoutPosition() и сохраняю в переменной экземпляра (я создал класс для представления этих данных, так же, как ожидается, что ContextMenuInfo будет работать), но более важно убедиться, что вы вернете false в этом методе. Все, что вам нужно сделать сейчас, это в oncontextitemselected (элемент MenuItem), прочитать данные, которые вы храните в переменной экземпляра, и если это действительно, Вы продолжаете свои действия. Вот фрагмент.

Я делаю ViewHolder реализует OnLongClickListener, но вы можете сделать это любым способом, который вы предпочитаете.

вы также можете установить это в адаптере или в другом представлении, которое у вас есть в ViewHolder (т. е. TextView). Важным является onLongClik() реализация.

лучшая часть заключается в том, что вы все еще можете обрабатывать событие LongClick, возвращающее true в случаях, которые вы хотите, и conextMenu не появится.

этот метод работает, потому что registerForContextView делает представление LongClickable, и когда его время для обработки ContextMenu, система вызывает performLongClick, который сначала вызывает реализацию onLongClick, и если он возвращает false, он затем вызывает showContextMenu.

Я использую это решение в течение некоторого времени и работал довольно хорошо для меня.

теперь в вашем фрагменте или действии реализуйте следующие методы.

наконец, зарегистрируйтесь для contextMenu на recyclerview

это должно сработать!

я боролся за это, потому что Android не справляется с этим хорошо для меня в RecyclerView, который работал очень хорошо для ListView.

самая сложная часть заключается в том, что часть ContextMenuInfo встроена в представление, которое вы не можете легко прикрепить, кроме переопределения представления.

поэтому вам понадобится обертка, которая поможет вам доставить информацию о позиции в действие.

тогда в вашем RecyclerAdapter, когда вы создаете ViewHolders, вам нужно установить оболочку как корневое представление и зарегистрировать contextMenu на каждом представлении.

и, наконец, в вашей деятельности, вы сможете делать то, что вы обычно делаете:

лучше всего было использовать контекстное меню с видом recycler, если вы сделаете пользовательский вид recycler и переопределите getContextMenuInfo() метод и вернуть свой собственный экземпляр объекта информации контекстного меню, так что вы можете получить позиции, когда он был создан и когда меню нажата:

Читайте также:  Как удалить cmm андроид

взгляните на эту суть, которую я создал:

расширение некоторых ответов выше немного, если вы хотите избежать ручного определения меню в коде в адаптере / держателе просмотра, то вы можете использовать PopupMenu и раздуть параметры меню из стандартного меню.xml-файл ресурсов.

пример ниже показывает это, включая возможность передачи прослушивателя, который вы можете реализовать в своем фрагменте/действии, чтобы ответить на щелчки контекстного меню.

Вы можете передать OnCreateContextMenuListener в ViewHolder на bind. Этот прослушиватель может создавать настраиваемое меню для каждого элемента данных. Просто добавьте setOnCreateContextMenuListener в свой ViewHolder и вызовите его во время привязки.

в моем случае мне пришлось использовать данные из моего фрагмента в onContextItemSelected() метод. Решение, с которым я закончил, состояло в том, чтобы передать экземпляр фрагмента в мой адаптер и зарегистрировать элемент представления в держателе представления:

затем в onCreateContextMenu() вы можете сохранить индекс в локальной переменной:

и восстановить его в onContextItemSelected()

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

начнем с пары классов утилит. ContextMenuHandler является интерфейсом для любого объекта, который будет обрабатывать контекстное меню. На практике это будет подкласс ViewHolder, но теоретически это может быть что угодно

Next-это интерфейс, который должен быть реализован любым представлением, которое будет использоваться в качестве непосредственного дочернего элемента RecyclerView.

далее, любое представление, которое собирается создать контекстное меню в качестве дочернего элемента RecylcerView, должно реализовать ViewWIthContextMenu. В моем случае, я нужен только подкласс LinearLayout.

и, наконец, нам нужен усиленный класс фрагментов для перехвата вызовов контекстного меню и перенаправления их в соответствующий обработчик.

со всем этим на месте, окончательная реализация довольно проста. Основной фрагмент имеет подкласс FragmentWithContextMenu. Он устанавливает основное окно RecylerWindow нормально и передает себя подклассу адаптера. Подкласс адаптера выглядит как

вот и все. Кажется, все работает. Он поместил все классы утилит в отдельный пакет contextmenu, чтобы я мог дать имена классов, которые соответствуют классам, которые есть подклассы, но я думал, что будет более запутанным.

вот как вы можете реализовать контекстное меню для RecyclerView и получить позицию элемента, для которого был выбран пункт контекстного меню:

Ok, основываясь на ответе @Flexo, я приведу mPosition в порядок.

затем в onContextItemSelected Я использую

и все работают нормально, я легко получаю позицию массива

Источник

Оцените статью