У меня есть адаптер, который настраивает recyclerView
, и я хочу открыть всплывающее меню в событии с длинным кликом на элементах recyclerView
.
Как я могу это сделать?
Обработка длинного клика мышью по просмотру ресайклера
Ответ 1
На это уже ответили здесь. В любом случае, вы можете сделать это так:
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
private Article article;
private TextView nameTextView;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
nameTextView = (TextView) itemView.findViewById(R.id.grid_item_article_name_textView);
}
public void bind(Article article) {
this.article = article;
nameTextView.setText(article.getName());
}
@Override
public void onClick(View view) {
// Context context = view.getContext();
// article.getName()
}
@Override
public boolean onLongClick(View view) {
// Handle long click
// Return true to indicate the click was handled
return true;
}
}
Обновление: если вы используете Kotlin, выполните:
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
View.OnClickListener, View.OnLongClickListener {
init {
itemView.setOnClickListener(this)
itemView.setOnLongClickListener(this)
}
private lateinit var article: Article
private val titleTextView: TextView = itemView.findViewById(R.id.item_article_title_textView)
fun bind(article: Article) {
this.article = article
titleTextView.text = article.title
}
override fun onClick(view: View) {
listener.onItemClick(article)
}
override fun onLongClick(view: View): Boolean {
Toast.makeText(view.context, "long click", Toast.LENGTH_SHORT).show()
// Return true to indicate the click was handled
return true
}
}
Ответ 2
Сначала вы должны зарегистрировать свою активность для прослушивания событий longClick из recyclerView
(так что вам не нужно использовать какой-либо onLongClickListener
...):
registerForContextMenu(recyclerView);
Затем вы создаете ресурс меню (context_menu.xml):
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="Mostra documento" android:id="@+id/context_menu_documents_fragment_view"></item>
<item android:title="Aggiungi ad un contenitore" android:id="@+id/context_menu_documents_fragment_add_to_box"></item>
<item android:title="Elimina documento" android:id="@+id/context_menu_documents_fragment_delete"></item>
</menu>
В действии, которое вы зарегистрировали для контекстного меню, вы переопределяете эти методы:
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
// Inflate Menu from xml resource
MenuInflater menuInflater = getActivity().getMenuInflater();
menuInflater.inflate(R.menu.context_menu_documents_fragment, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
Toast.makeText(getActivity(), " User selected something ", Toast.LENGTH_LONG).show();
return false;
}
Это очень важно, вам нужно изменить код в адаптере recyclerView
следующим образом:
@Override
public void onBindViewHolder(final DocumentViewHolder viewHolder, int position) {
...
viewHolder.itemView.setLongClickable(true);
...
}
Теперь вы можете показать контекстное меню и перехватить выбор пользователя! Но вы не можете узнать, какой элемент пользователь нажал, для этого вам нужно использовать собственный RecyclerView (исходный код от Renaud Cerrato):
public class ContextMenuRecyclerView extends RecyclerView {
private RecyclerContextMenuInfo mContextMenuInfo;
public ContextMenuRecyclerView(Context context) {
super(context);
}
public ContextMenuRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ContextMenuRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected ContextMenu.ContextMenuInfo getContextMenuInfo() {
return mContextMenuInfo;
}
@Override
public boolean showContextMenuForChild(View originalView) {
final int longPressPosition = getChildAdapterPosition(originalView);
if (longPressPosition >= 0) {
final long longPressId = getAdapter().getItemId(longPressPosition);
mContextMenuInfo = new RecyclerContextMenuInfo(longPressPosition, longPressId);
return super.showContextMenuForChild(originalView);
}
return false;
}
public static class RecyclerContextMenuInfo implements ContextMenu.ContextMenuInfo {
public RecyclerContextMenuInfo(int position, long id) {
this.position = position;
this.id = id;
}
final public int position;
final public long id;
}
}
В предыдущем методе onContextItemSelected()
вы можете узнать идентификатор и позицию элемента recyclerView
, используя этот код:
ContextMenuRecyclerView.RecyclerContextMenuInfo info = (ContextMenuRecyclerView.RecyclerContextMenuInfo) item.getMenuInfo();
Наконец, вам нужно изменить метод getItemId() в вашем адаптере recyclerView и файле макета, чтобы убедиться, что вы используете ваш recyclerView, а не андроид!
Ответ 3
Я сделал так:
static class ViewHolder extends RecyclerView.ViewHolder {
TextView tvName;
ViewHolder(View v) {
super(v);
tvName = (TextView) v.findViewById(R.id.textView_Username);
//Single Tapup
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Position is " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
//Long Press
v.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Toast.makeText(v.getContext(), "Position is " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
return false;
}
});
}
}
Ответ 4
Я изо всех сил старался найти позицию элемента на клике, это сработало для меня:
public void onClick(View view) {
ViewHolder holder =(ViewHolder)view.getTag();
int position = holder.getLayoutPosition();
Log.d("testing ","pos" +position);
}