Estoy en sustitución de mi ListView con RecyclerView, listado de aceptar, pero me gustaría saber cómo conseguir hacer clic elemento y su posición, similar a la del método OnItemClickListener.onItemClick(AdapterView padre, View v, int position, long id) utilizamos en ListView.

Gracias por las ideas!

InformationsquelleAutor Xcihnegn | 2015-02-03

17 Comentarios

  1. 160

    Basada en el vínculo: ¿Por qué no RecyclerView han onItemClickListener()? y Cómo RecyclerView es diferente de Listview?, y también @Duncan idea general, yo doy la solución aquí:

    • Definir una interfaz RecyclerViewClickListener para pasar el mensaje de adaptador de Activity/Fragment:

      public interface RecyclerViewClickListener {
          public void recyclerViewListClicked(View v, int position);
      }
    • En Activity/Fragment implementar la interfaz, y también pasar el oyente adaptador:

      @Override
      public void recyclerViewListClicked(View v, int position){... ...}
      
      //set up adapter and pass clicked listener this
      myAdapter = new MyRecyclerViewAdapter(context, this);
    • En Adapter y ViewHolder:

      public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ItemViewHolder> {
         ... ... 
         private Context context;
         private static RecyclerViewClickListener itemListener;
      
      
         public MyRecyclerViewAdapter(Context context, RecyclerViewClickListener itemListener) {
             this.context = context;
             this.itemListener = itemListener;
             ... ...
         }
      
      
         //ViewHolder class implement OnClickListener, 
         //set clicklistener to itemView and, 
         //send message back to Activity/Fragment 
         public static class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
             ... ...
             public ItemViewHolder(View convertView) {
                 super(convertView);
                 ... ...
                 convertView.setOnClickListener(this);
             }
      
             @Override
             public void onClick(View v) {
                 itemListener.recyclerViewListClicked(v, this.getPosition());     
      
             }
         }
      }

    Después de la prueba, funciona bien.


    [ACTUALIZACIÓN]

    Desde la API de 22 de RecyclerView.ViewHoler.getPosition() está en desuso, por lo que en lugar, con getLayoutPosition().

    • uso getLayoutPosition() método como getPosition() es depricated ahora.
    • Sí que es cierto para las API de 22, que se acaba de actualización de la respuesta
    • gracias por este pedazo de código 🙂 sólo un consejo: hacer referencia a la estática private static RecyclerViewClickListener itemListener; en una manera estática en el constructor.
    • gracias por su ayuda. ¿cómo podemos agregar pase en las tarjetas?
    • ¿Qué pasa si no quiero RecyclerViewClickListenera ser estática? Por ejemplo, tengo 3 pestañas que utiliza el mismo tipo de adaptador y los tres implementar RecyclerViewClickListener. Pero si no es estática, cómo usarlo dentro de static class ItemViewHolde ?
    • Negre esto es exactamente lo que estoy buscando. Tienes la respuesta?
    • Terminé la adición de un detector en cada elemento en el método onBindViewHolder. Por otra parte, mi elemento de la lista no fue todo clickable (sólo parte del artículo).
    • upvote para el mismo mensaje de aviso.
    • Si quiero utilizar este Detector de enfoque para eliminar elementos del conjunto de datos y la vista. Funciona para el primer elemento, pero entonces el índice se desplaza en +1 cada una de las subsiguientes eliminar. Traté de usar adapter.notifyItemRemoved(pos), pero no ayuda
    • cómo conseguir el clic elemento objeto de la actividad de adaptador de android.necesito más trasnparencia, estoy haciendo como por u r instrucción elemento, haga clic en el oyente no se llama
    • Si usted no está usando un WeakReference aquí: new MyRecyclerViewAdapter(context, this)? Esto puede provocar pérdidas de memoria
    • public void recyclerViewListClicked(View v, int position); El modificador public es redundante para la interfaz de los métodos de
    • puede el «este.getPosition()» se sustituyen por «de este.getAdapterPosition()»?
    • Gracias man u salvó mi día me han implementado su solución en expandableRV caso y Funcionó!
    • agradable, funciona como un encanto
    • En onclick en el interior de ItemViewHolderclass, estamos pasando itemListener.recyclerViewListClicked(v, este.getPosition());, en lugar usted puede pasar recyclerviewItemClickListener.OnItemClick(ver,getAdapterPosition());esto también.
    • Esta es una respuesta excelente, va muy amable con la limpieza de la arquitectura y el patrón mvp 🙂

  2. 29
    public class MyRvAdapter extends RecyclerView.Adapter<MyRvAdapter.MyViewHolder>{
        public Context context;
        public ArrayList<RvDataItem> dataItems;
    
        ...
        constructor
        overrides
        ...
    
        class MyViewHolder extends RecyclerView.ViewHolder{
            public TextView textView;
            public Context context;
    
            public MyViewHolder(View itemView, Context context) {
                super(itemView);
    
                this.context = context;
    
                this.textView = (TextView)itemView.findViewById(R.id.textView);
    
                //on item click
                itemView.setOnClickListener(new View.OnClickListener(){
                    @Override
                    public void onClick(View v) {
                        //get position
                        int pos = getAdapterPosition();
    
                        //check if item still exists
                        if(pos != RecyclerView.NO_POSITION){
                            RvDataItem clickedDataItem = dataItems.get(pos);
                            Toast.makeText(v.getContext(), "You clicked " + clickedDataItem.getName(), Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }
        }
    }
    • Gracias. getAdapterPosition() es lo que yo necesitaba.
    • Gracias por el código man!! Me salvó el día. Yo no estaba seguro de donde poner getAdapterPosition() y siguiendo el código yo tengo trabajo… Agradable y fácil 🙂
  3. 13

    Aquí es un Ejemplo para establecer un Clic en el Oyente.

    Adapter extends  RecyclerView.Adapter<MessageAdapter.MessageViewHolder> {  ...  }
    
     public static class MessageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
            public TextView     tv_msg;
            public TextView     tv_date;
            public TextView     tv_sendTime;
            public ImageView    sharedFile;
            public ProgressBar sendingProgressBar;
    
            public MessageViewHolder(View v) {
                super(v);
                tv_msg =  (TextView) v.findViewById(R.id.tv_msg);
                tv_date = (TextView)  v.findViewById(R.id.tv_date);
                tv_sendTime = (TextView)  v.findViewById(R.id.tv_sendTime);
                sendingProgressBar = (ProgressBar) v.findViewById(R.id.sendingProgressBar);
                sharedFile = (ImageView) v.findViewById(R.id.sharedFile);
    
                sharedFile.setOnClickListener(this);
    
            }
    
            @Override
            public void onClick(View view) {
            int position  =   getAdapterPosition();
    
    
                switch (view.getId()){
                    case R.id.sharedFile:
    
    
                        Log.w("", "Selected"+position);
    
    
                        break;
                }
            }
    
        }
    • ¿Qué es getAdapterPostion(); aquí?
    • la posición de la vista se hace clic. no es un método personalizado.
    • Esto parece la forma más limpia para hacer esto, especialmente desde que está casi siempre interesado en la obtención de datos a partir de la posición y no puede tener acceso a la RecyclerView objeto.
    • Muchas gracias por int position = getAdapterPosition();
    • Por favor tome nota de que llamar a getAdapterPosition mientras que la lista se actualiza, por ejemplo, debido a llamar notififyXYZ, devolverá -1
    • leer esto: stackoverflow.com/questions/29684154/…
    • He leído que uno es por eso que he publicado mi comentario.

  4. 11

    Poner este código en el que se definen reciclador de vista de la actividad.

        rv_list.addOnItemTouchListener(
                new RecyclerItemClickListener(activity, new RecyclerItemClickListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View v, int position) {
    
                        Toast.makeText(activity, "" + position, Toast.LENGTH_SHORT).show();
                    }
                })
        );

    A continuación, haga independiente de la clase y poner este código:

    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.view.View;
    public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    
        private OnItemClickListener mListener;
        public interface OnItemClickListener {
            public void onItemClick(View view, int position);
        }
        GestureDetector mGestureDetector;
        public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
            mListener = listener;
            mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return true;
                }
            });
        }
        @Override
        public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
            View childView = view.findChildViewUnder(e.getX(), e.getY());
            if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
                mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
            }
            return false;
        }
    
        @Override
        public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
        }
    
        @Override
        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    
        }
    }
  5. 5

    Si quieres haga Clic en evento de reciclaje de Vista de la actividad/fragmento en lugar de adaptador, entonces también se puede utilizar la siguiente forma de corte.

    recyclerView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    final TextView txtStatusChange = (TextView)v.findViewById(R.id.txt_key_status);
                    txtStatusChange.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Log.e(TAG, "hello text " + txtStatusChange.getText().toString() + " TAG " + txtStatusChange.getTag().toString());
                            Util.showToast(CampaignLiveActivity.this,"hello");
                        }
                    });
                    return false;
                }
            });

    También puede utilizar otras formas como el uso de la interfaz de

    • ,, hola,, pero lo que si tenemos que obtener la posición del elemento clic así. ?
    • Sólo puede establecer la posición del elemento en la ETIQUETA a través de un adaptador y, a continuación, obtener la etiqueta como se mencionó anteriormente txtStatusChange.getTag().toString()
    • En orden para que el código funcione, tengo que desplazarse hasta el final de la horizontal recyclerview primera. Sólo entonces se hace el brindis de trabajo. No hay una forma de hacer el trabajo sin tener que desplazarse adelante y atrás en el primer lugar?
  6. 4
    recyclerViewObject.addOnItemTouchListener(
        new RecyclerItemClickListener(
            getContext(),
            recyclerViewObject,
            new RecyclerItemClickListener.OnItemClickListener() {
                @Override public void onItemClick(View view, int position) {
                    //view is the clicked view (the one you wanted
                    //position is its position in the adapter
                }
                @Override public void onLongItemClick(View view, int position) {
                }
            }
        )
    );
    • Qué brujería es esta? Funciona a la perfección.
  7. 4

    crear archivo java con el código de abajo,

    public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
    private OnItemClickListener mListener;
    
    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }
    
    GestureDetector mGestureDetector;
    
    public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
        mListener = listener;
        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    }
    
    @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
            mListener.onItemClick(childView, view.getChildLayoutPosition(childView));
            return true;
        }
        return false;
    }
    
    @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
    
    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    
    }

    y sólo tiene que utilizar el detector en su RecyclerView objeto.

    recyclerView.addOnItemTouchListener(  
    new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
      @Override public void onItemClick(View view, int position) {
        //TODO Handle item click
      }
    }));
    • RecyclerItemClickListener no es un android por defecto de la clase, usted debe proporcionar la biblioteca está utilizando o de la misma clase.
    • thanx !! se me olvidó post!!!
    • bueno……..
  8. 2

    Utilizar a continuación el código:-

    public class SergejAdapter extends RecyclerView.Adapter<SergejAdapter.MyViewHolder>{
    
    ...
    
    class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
    
    
        @Override
        public void onClick(View v) {
            //here you use position
            int position = getAdapterPosition();
            ...
    
        }
    }
    }
  9. 1

    RecyclerView no proporciona dicho método.

    Para gestionar los eventos de clic en RecyclerView terminé la aplicación de onClickListener en mi adaptador, cuando la unión de la ViewHolder: En mi ViewHolder puedo mantener una referencia a la raíz de la vista (como usted puede hacer con su ImageViews, TextViews, etc…) y cuando la unión de la viewHolder me puse una etiqueta con la información que necesita para manejar haga clic en (tales como la posición) y un clicklistener

    • sí podemos establecer haga clic en el oyente en ViewHolder, pero necesito pasar de nuevo el artículo pulsado la vista y a la posición de mi fragmento para seguir el proceso de
  10. 0
    //Create below methods into the Activity which contains RecyclerView.
    
    
    private void createRecyclerView() {
    
    final RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        MyAdapter myAdapter=new MyAdapter(dataAray,MianActivity.this);
        recyclerView.setAdapter(myAdapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
    
        setRecyclerViewClickListner(recyclerView);
    }
    
    private void setRecyclerViewClickListner(RecyclerView recyclerView){
    
        final GestureDetector gestureDetector = new GestureDetector(MainActivity.this,new GestureDetector.SimpleOnGestureListener() {
            @Override public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }
        });
    
    
        recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
                View child =recyclerView.findChildViewUnder(motionEvent.getX(),motionEvent.getY());
                if(child!=null && gestureDetector.onTouchEvent(motionEvent)){
                   int position=recyclerView.getChildLayoutPosition(child);
                    String name=itemArray.get(position).name;
    
                return true;
            }
    
            @Override
            public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
    
            }
    
            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean b) {
    
            }
        });
    }
    • Por favor, agregue una explicación, solo el dumping de código sin introducción y una explicación de cómo esto soluciona el problema, no es muy útil.
  11. 0

    Tratar de esta manera

    Adaptador de clase :

     public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {
    public interface OnItemClickListener {
    void onItemClick(ContentItem item);
    }
    private final List<ContentItem> items;
    private final OnItemClickListener listener;
    public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
    this.items = items;
    this.listener = listener;
    }
    @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false);
    return new ViewHolder(v);
    }
    @Override public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bind(items.get(position), listener);
    }
    @Override public int getItemCount() {
    return items.size();
    }
    static class ViewHolder extends RecyclerView.ViewHolder {
    private TextView name;
    private ImageView image;
    public ViewHolder(View itemView) {
    super(itemView);
    name = (TextView) itemView.findViewById(R.id.name);
    image = (ImageView) itemView.findViewById(R.id.image);
    }
    public void bind(final ContentItem item, final OnItemClickListener listener) {
    name.setText(item.name);
    itemView.setOnClickListener(new View.OnClickListener() {
    @Override public void onClick(View v) {
    listener.onItemClick(item);
    }
    });
    }
    }

    }

    En su Actividad o fragmento :

    ContentAdapter adapter = new ContentAdapter(itemList, this);

    Nota : Implementar el OnItemClickListener basada en el contexto dado por usted en la actividad o el fragmento y dominen los métodos.

    • Agradable la solución anterior. Se puede agregar a la anterior para mostrar lo que el método onItemClick debe verse como en la Actividad? Estoy tratando de pasar el elemento de la posición de una Intención (para abrir la siguiente Actividad) y sigo recibiendo la posición incorrecta.
  12. 0

    Cada vez que lo uso otro enfoque. Parece que la gente de la tienda o de obtener la posición de un punto de vista, en lugar de almacenar una referencia a un objeto que se muestra por ViewHolder.

    Puedo utilizar este enfoque en su lugar, y acaba de guardar en ViewHolder cuando onBindViewHolder() es llamado, y establecer una referencia a null en onViewRecycled().

    Cada vez ViewHolder se vuelve invisible, que es reciclado. Así que esto no afecta en gran consumo de memoria.

    @Override
    public void onBindViewHolder(final ItemViewHolder holder, int position) {
    ...
    holder.displayedItem = adapterItemsList.get(i);
    ...
    }
    @Override
    public void onViewRecycled(ItemViewHolder holder) {
    ...
    holder.displayedItem = null;
    ...
    }
    class ItemViewHolder extends RecyclerView.ViewHolder {
    ...
    MySuperItemObject displayedItem = null;
    ...
    }
  13. 0

    Corta extensión para Kotlin

    Método devuelve la posición absoluta de todos los elementos (no la posición de los elementos visibles únicamente).

    fun RecyclerView.getChildPositionAt(x: Float, y: Float): Int {
    return getChildAdapterPosition(findChildViewUnder(x, y))
    }

    Y la utilización de los

    val position = recyclerView.getChildPositionAt(event.x, event.y)
  14. 0

    Aquí es la más sencilla y la forma más fácil de encontrar la posición del ítem pulsado:

    También he enfrentado el mismo problema.

    Quería saber de la posición del clic/elemento seleccionado de la RecyclerView() y realizar algunas operaciones específicas sobre ese tema en particular.

    getAdapterPosition() método que funciona como un encanto para este tipo de cosas. He encontrado este método después de un día de largas investigaciones y después de probar muchos otros métodos.

    int position = getAdapterPosition();
    Toast.makeText(this, "Position is: "+position, Toast.LENGTH_SHORT).show();

    No tener que utilizar un método extra. Sólo tienes que crear una variable global llamada ‘la posición’ y la inicializamos con getAdapterPosition() en cualquiera de las principales método del adaptador (clase o similar).

    Aquí es una breve documentación de este enlace.

    getAdapterPosition
    añadido en la versión 22.1.0
    int getAdapterPosition ()
    Devuelve la posición del Adaptador del elemento representado por este ViewHolder.
    Tenga en cuenta que esto puede ser diferente de la getLayoutPosition() si hay pendientes adaptador de actualizaciones, pero una nueva fase de diseño no ha sucedido todavía.
    RecyclerView no manejar cualquier adaptador de actualizaciones hasta la próxima diseño del recorrido. Esto puede crear inconsistencias temporales entre lo que el usuario ve en la pantalla y lo del adaptador de contenido. Esta inconsistencia no es importante, ya que será menos de 16ms, pero podría ser un problema si usted desea utilizar ViewHolder posición para acceder al adaptador. A veces, es posible que necesite obtener la exacta posición del adaptador para hacer algunas acciones en respuesta a eventos del usuario. En ese caso, usted debe utilizar este método de calcular la posición del Adaptador de la ViewHolder.

    Feliz de ayudar. Siéntase libre de preguntar dudas.

  15. 0

    Uso getLayoutPosition() en la interfaz personalizada método java. Esto devolverá la posición seleccionada de un elemento, echa un detalle completo sobre

    https://becody.com/get-clicked-item-and-its-position-in-recyclerview/

    • Bienvenido a Desbordamiento de Pila! Mientras que los vínculos son una gran manera de compartir el conocimiento, que realmente no responder a la pregunta de si se rompen en el futuro. Añadir a su respuesta el contenido esencial de la vinculación que se responde a la pregunta. En caso de que el contenido es demasiado complejo o demasiado grande para caber aquí, describir la idea general de la solución propuesta. Recuerde que debe mantener siempre un enlace de referencia para la solución original del sitio web. Ver: ¿Cómo puedo escribir una buena respuesta?
  16. 0

    Del diseñador, usted puede establecer la onClick propiedad de la listItem a un método definido con un solo parámetro. Tengo un ejemplo de método se define a continuación. El método getAdapterPosition le dará el índice de los seleccionados listItem.

    public void exampleOnClickMethod(View view){
    myRecyclerView.getChildViewHolder(view).getAdapterPosition());
    }

    Para obtener información sobre la configuración de un RecyclerView, consulte la documentación aquí: https://developer.android.com/guide/topics/ui/layout/recyclerview

  17. -4

    En onViewHolder conjunto onClickListiner a cualquier punto de vista y en el lado haga clic en usar este código :

    Tostadas.makeText(Drawer_bar.esta «posición» + posición, Tostadas.LENGTH_SHORT).show();

    Reemplazar Drawer_Bar con el nombre de la Actividad.

Dejar respuesta

Please enter your comment!
Please enter your name here