Tengo un adaptador que permite personalizar una recyclerView y quiero abrir un menú emergente en la larga haga clic en evento en recyclerView‘s elementos.
¿Cómo puedo hacer esto?

4 Comentarios

  1. 36

    Esto ya ha sido contestado aquí. De todos modos, usted puede hacer esto de esta manera:

    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;
        }
    }

    Actualización: si usted está usando Kotlin hacer:

    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
        }
    }
    • Usted tiene que conseguir que el oyente hacia el Viewholder pero aún así es mucho más fácil que todos los directa de las resoluciones de la adición de TouchListeners a la RecylerView
  2. 11

    Primer lugar, usted tiene que registrar su Actividad a escuchar longClick eventos de la recyclerView (así que usted no tiene que utilizar ningún tipo de onLongClickListener…):

    registerForContextMenu(recyclerView);

    A continuación, crear un menú de recursos (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>

    En la actividad en la que se registró en el menú de contexto que invalide este métodos:

    @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;
        }

    Esto es muy importante, tienes que modificar el código de la RecyclerView adaptador como este:

    @Override
        public void onBindViewHolder(final DocumentViewHolder viewHolder, int position) {
    
            ...
            viewHolder.itemView.setLongClickable(true);
            ...
        }

    Ahora usted es capaz de mostrar el menú contextual y la intersección de la selección del usuario!
    Pero usted no es capaz de saber el elemento que el usuario hace clic en, para hacer esto usted tiene que utilizar una costumbre RecyclerView como este (código original en el 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;
        }
    
    }

    En el anterior onContextItemSelected() método se puede conocer la recyclerView id de elemento y su posición usando este código:

    ContextMenuRecyclerView.RecyclerContextMenuInfo info = (ContextMenuRecyclerView.RecyclerContextMenuInfo) item.getMenuInfo();

    Finalmente tiene que modificar el getItemId() método en su recyclerView adaptador y el archivo de diseño para asegurarse de que usted utilice su recyclerView y no el de android uno!

  3. 7

    Yo lo hice de esta manera:

    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. 2

    Estaba luchando duro para recuperar la posición del elemento en el clic, esto funcionó para mí :

    public void onClick(View view) {
        ViewHolder holder =(ViewHolder)view.getTag();
        int position = holder.getLayoutPosition();
        Log.d("testing ","pos" +position);
    }
    • int = getAdapterPosition() devolverá la posición de clic elemento.

Dejar respuesta

Please enter your comment!
Please enter your name here