studio recyclerview onitemtouchlistener new item example cardview activity android onclick android-recyclerview onclicklistener

android - onitemtouchlistener - RecyclerView onClick



recyclerview onitemclicklistener example in android (30)

Marque la clase como abstracta e implemente un método OnClick

public abstract class MainGridAdapter extends RecyclerView.Adapter<MainGridAdapter.ViewHolder> { private List<MainListItem> mDataset; // Provide a reference to the views for each data item // Complex data items may need more than one view per item, and // you provide access to all the views for a data item in a view holder public class ViewHolder extends RecyclerView.ViewHolder { // each data item is just a string in this case public TextView txtHeader; public TextView txtFooter; public ViewHolder(View v) { super(v); txtHeader = (TextView) v.findViewById(R.id.firstLine); txtFooter = (TextView) v.findViewById(R.id.secondLine); } } public void add(int position, MainListItem item) { mDataset.add(position, item); notifyItemInserted(position); } public void remove(MainListItem item) { int position = mDataset.indexOf(item); mDataset.remove(position); notifyItemRemoved(position); } // Provide a suitable constructor (depends on the kind of dataset) public MainGridAdapter(List<MainListItem> myDataset) { mDataset = myDataset; } // Create new views (invoked by the layout manager) @Override public MainGridAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View v = LayoutInflater.from(parent.getContext()).inflate( R.layout.list_item_grid_line, parent, false); // set the view''s size, margins, paddings and layout parameters ViewHolder vh = new ViewHolder(v); return vh; } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(final ViewHolder holder, final int position) { // - get element from your dataset at this position // - replace the contents of the view with that element OnClickListener clickListener = new OnClickListener() { @Override public void onClick(View v) { onItemClicked(position); } }; holder.itemView.setOnClickListener(clickListener); holder.txtHeader.setOnClickListener(clickListener); holder.txtFooter.setOnClickListener(clickListener); final MainListItem item = mDataset.get(position); holder.txtHeader.setText(item.getTitle()); if (TextUtils.isEmpty(item.getDescription())) { holder.txtFooter.setVisibility(View.GONE); } else { holder.txtFooter.setVisibility(View.VISIBLE); holder.txtFooter.setText(item.getDescription()); } } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.size(); } public abstract void onItemClicked(int position);

}

Implementar el controlador de clic en el evento de enlace para tener solo una implementación de evento

Implementación de esto:

mAdapter = new MainGridAdapter(listItems) { @Override public void onItemClicked(int position) { showToast("Item Clicked: " + position, ToastPlus.STYLE_INFO); } };

Lo mismo se puede hacer para un clic largo

¿Alguien que usa RecyclerView encontrado una manera de configurar un onClickListener a los elementos en RecyclerView ? Pensé en establecer un oyente en cada uno de los diseños para cada elemento, pero eso parece un poco demasiado complicado. Estoy seguro de que hay una forma para que RecyclerView escuche el evento onClick pero no puedo entenderlo.


aquí está el código completo para mi adaptador personalizado este código inflará las filas con los elementos de lista definidos en el archivo xml llamado "list_item" y también realizará un evento de clic en todas las filas de elementos de lista con las posiciones respectivas.

clase pública MyCustomAdapter extiende RecyclerView.Adapter <AdapterMyCustomAdapter.ViewHolder> {

public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener{ public onItemClickListener mListener; public ViewHolder(View v, onItemClickListener listener) { super(v); mListener =listener; v.setOnClickListener(this); } @Override public void onClick(View v) { mListener.onRecyclerItemClick(v, getPosition()); } public static interface onItemClickListener { public void onRecyclerItemClick(View view , int position); } } @Override public int getItemCount() { return 5; } @Override public void onBindViewHolder(ViewHolder holder, int pos) { } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int position) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.list_item, parent, false); /* here list_item is an xml file we want to inflate ...it is same as we do in case of listview for customization.*/ MyCustomAdapter.ViewHolder vh = new ViewHolder(v, new MyCustomAdapter.ViewHolder.onItemClickListener() { @Override public void onRecyclerItemClick(View view, int position) { System.out.println("clicked on list item at position " +position); } }); return vh; }

}


Aquí esta lo que hice. Esta solución admite tanto OnClick como onLongClick tanto en RecyclerView Items como en Views dentro de RecyclerView Items (vistas internas).

Etiqueto viewHolder en las vistas de mi elección:

public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item, null); ViewHolder viewHolder = new ViewHolder(itemView); itemView.setOnClickListener( this); itemView.setOnLongClickListener(this); viewHolder.imageIV.setOnClickListener(this); viewHolder.imageIV.setOnLongClickListener(this); viewHolder.imageIV.setTag(viewHolder); itemView.setTag(viewHolder); return viewHolder; }

Y uso holder.getPosition () para recuperar la posición en el método onClick () (onLongClick es similar):

public void onClick(View view) { ViewHolder holder = (ViewHolder) view.getTag(); int position = holder.getPosition(); if (view.getId() == holder.imageIV.getId()){ Toast.makeText(context, "imageIV onClick at" + position, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "RecyclerView Item onClick at " + position, Toast.LENGTH_SHORT).show(); } }

Una variante con getChildPosition también funciona. Tenga en cuenta que para las vistas internas, en el uso de onClick ():

int position = recyclerView.getChildPosition((View)view.getParent());

En mi opinión, la ventaja de esta solución es que cuando se hace clic en la imagen, solo se llama al oyente de imagen onclick (), mientras que cuando combiné la solución de Jacob para una vista del elemento RecyclerView y mi solución para las vistas internas, la vista del elemento RecyclerView onclick ) También se llama (cuando se hace clic en la imagen).


Aquí hay una forma mejor y menos estrechamente acoplada de implementar un OnClickListener para un RecyclerView .

Fragmento de uso:

RecyclerView recyclerView = findViewById(R.id.recycler); recyclerView.addOnItemTouchListener( new RecyclerItemClickListener(context, recyclerView ,new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { // do whatever } @Override public void onLongItemClick(View view, int position) { // do whatever } }) );

Implementación RecyclerItemClickListener :

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); public void onLongItemClick(View view, int position); } GestureDetector mGestureDetector; public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) { mListener = listener; mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public void onLongPress(MotionEvent e) { View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (child != null && mListener != null) { mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child)); } } }); } @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 true; } return false; } @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { } @Override public void onRequestDisallowInterceptTouchEvent (boolean disallowIntercept){} }


Basándome en la respuesta de Jacob Tabak (+1 para él), pude agregar la escucha onLongClick:

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 { public interface OnItemClickListener { void onItemClick(View view, int position); void onItemLongClick(View view, int position); } private OnItemClickListener mListener; private GestureDetector mGestureDetector; public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) { mListener = listener; mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public void onLongPress(MotionEvent e) { View childView = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener != null) { mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView)); } } }); } @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) { } }

Entonces puedes usarlo así:

recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { // ... } @Override public void onItemLongClick(View view, int position) { // ... } }));


Como los API han cambiado radicalmente, no me sorprendería si creara un OnClickListener para cada elemento. Aunque no es mucho de una molestia. En su implementación de RecyclerView.Adapter<MyViewHolder> , debe tener:

private final OnClickListener mOnClickListener = new MyOnClickListener(); @Override public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false); view.setOnClickListener(mOnClickListener); return new MyViewHolder(view); }

El método onClick :

@Override public void onClick(final View view) { int itemPosition = mRecyclerView.getChildLayoutPosition(view); String item = mList.get(itemPosition); Toast.makeText(mContext, item, Toast.LENGTH_LONG).show(); }


Demasiado simple y eficaz.

En lugar de implementar la interfaz View.OnClickListener dentro del titular de la vista o crear e interconectar e implementar la interfaz en su actividad, utilicé este código para simplificar la implementación de OnClickListener .

public static class SimpleStringRecyclerViewAdapter extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> { // Your initializations goes here... private List<String> mValues; public static class ViewHolder extends RecyclerView.ViewHolder { //create a variable mView public final View mView; /*All your row widgets goes here public final ImageView mImageView; public final TextView mTextView;*/ public ViewHolder(View view) { super(view); //Initialize it here mView = view; /* your row widgets initializations goes here mImageView = (ImageView) view.findViewById(R.id.avatar); mTextView = (TextView) view.findViewById(android.R.id.text1);*/ } } public String getValueAt(int position) { return mValues.get(position); } public SimpleStringRecyclerViewAdapter(Context context, List<String> items) { mBackground = mTypedValue.resourceId; mValues = items; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.list_item, parent, false); view.setBackgroundResource(mBackground); return new ViewHolder(view); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.mBoundString = mValues.get(position); holder.mTextView.setText(mValues.get(position)); //Here it is simply write onItemClick listener here holder.mView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Context context = v.getContext(); Intent intent = new Intent(context, ExampleActivity.class); context.startActivity(intent); } }); } @Override public int getItemCount() { return mValues.size(); } }


Echa un vistazo a una question similar en el enlace de comentarios de CommonsWare , que implementa la interfaz OnClickListener en viewHolder .

Aquí hay un ejemplo simple de ViewHolder :

TextView textView;//declare global with in adapter class public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); textView = (TextView)view.findViewById(android.R.id.text1); } @Override public void onClick(View view) { Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show(); //go through each item if you have few items within recycler view if(getLayoutPosition()==0){ //Do whatever you want here }else if(getLayoutPosition()==1){ //Do whatever you want here }else if(getLayoutPosition()==2){ }else if(getLayoutPosition()==3){ }else if(getLayoutPosition()==4){ }else if(getLayoutPosition()==5){ } //or you can use For loop if you have long list of items. Use its length or size of the list as for(int i = 0; i<exampleList.size(); i++){ } } }

El Adapter se ve así:

@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view =LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false); return new ViewHolder(view); }


Esto es lo que funcionó para mí. Adjunte el OnClickListener al onBindView . Realmente no sé si esto afectará el rendimiento, pero parece funcionar bien con poco código.

public void onBindViewHolder(ViewHolder holder, final int position) { holder.view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(context, "Recycle Click" + position, Toast.LENGTH_SHORT).show(); } }); }


Esto es lo que terminé necesitando, en caso de que alguien lo encuentre útil:

public static class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View item) { super(item); item.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.d("RecyclerView", "onClick:" + getAdapterPosition()); } }); } }

Fuente: http://blog.csdn.net/jwzhangjie/article/details/36868515


Esto fue tan difícil para mí tener en el elemento de escucha de clics en la actividad y también para tener clic de escucha para la vista única del elemento que no se activará en el elemento de escucha de clic. Después de jugar con la respuesta de Jacob Tabak, respeto su respuesta por el clic en el elemento si no se presentan otras acciones táctiles dentro del elemento.

Tengo una interfaz OnClickListener personalizada que tiene el evento de clic de elemento que contiene la vista del elemento seleccionado y la posición del elemento desde el adaptador. Presento una instancia del mismo en el constructor (o puede ser con el configurador) y lo adjunto al oyente del contenedor del titular de la vista.

También tengo otro detector de clics en el Adaptador (puede estar en el titular de la vista) que manejará el clic actual de Vista desde el contenedor.

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> { private ArrayList<String> mData; private OnItemClickListener mOnItemClickListener; public interface OnItemClickListener { public void onItemClick(View view, int position); } public MyRecyclerAdapter(ArrayList<String> itemsData, OnItemClickListener onItemClickListener) { mOnItemClickListener = onItemClickListener; this.mData = itemsData; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View layoutView = LayoutInflater.from(mContext).inflate( R.layout.list_item, parent, false); MyViewHolder viewHolder = new MyViewHolder(layoutView); return viewHolder; } @Override public void onBindViewHolder(MyViewHolder viewHolder, final int position) { viewHolder.container.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mOnItemClickListener.onItemClick(v, position); } }); viewHilder.button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //do button click work here } }); } @Override public int getItemCount() { return mData.size(); }}

En la actividad, necesita inicializar el adaptador pasando la instancia de OnItemClickListener

public class FeedActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); ..... MyRecyclerAdapter adapter = new MyRecyclerAdapter(new ArrayList<String>(), new OnItemClickListener() { @Override public void onItemClick(View view, int position) { ///list item was clicked } }); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setAdapter(mFeedsAdapter); }

Y mi ViewHolder

public class MyViewHolder extends RecyclerView.ViewHolder { public Button button; public View container; public MyViewHolder(View itemLayoutView) { super(itemLayoutView); container = itemLayoutView; button = (Button) itemLayoutView.findViewById(R.id.button); }}


Hay una manera mucho más fácil de hacer esto. Simplemente haga clic en onBindViewHolder en la vista raíz.

Considera que esta es tu opinión para el adaptador,

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/linearlayout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/textview" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="1dp" android:textSize="15sp" /> </LinearLayout>

Entonces sigue en tu adaptador

//get the layout and make view holder @Override public RVAdapter.ViewHolder1 onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_layout, null); ViewHolder1 viewHolder = new ViewHolder1(view); return viewHolder; } @Override public void onBindViewHolder(RVAdapter.ViewHolder1 holder, int position) { //apply on click on your root view holder.linearlayout.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Do on click stuff } }); } //make references to views in layout including root view public class ViewHolder1 extends RecyclerView.ViewHolder { protected LinearLayout linearlayout = null protected TextView textview = null; public CareerLinksViewHolder(View itemView) { super(itemView); this.linearlayout = (LinearLayout) itemView.findViewById(R.id.linearlayout); this.tvCompName = (TextView) itemView.findViewById(R.id.textview); } }


He desarrollado una biblioteca ligera para Android, puedes visitar https://github.com/ChathuraHettiarachchi/RecycleClick

y seguir para la siguiente muestra

RecycleClick.addTo(YOUR_RECYCLEVIEW).setOnItemClickListener(new RecycleClick.OnItemClickListener() { @Override public void onItemClicked(RecyclerView recyclerView, int position, View v) { // YOUR CODE } });


Lo hago de esta manera, sin clases indebidas, detectores, etc. Código simple dentro de nuestro adaptador. Especialmente mejor solución para longClick que la presentada anteriormente.

public class PasswordAdapter extends RecyclerView.Adapter<PasswordAdapter.ViewHolder> { private static ClickListener clickListener; public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { TextView name; public ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); itemView.setOnLongClickListener(this); name = (TextView) itemView.findViewById(R.id.card_name); } @Override public void onClick(View v) { clickListener.onItemClick(getAdapterPosition(), v); } @Override public boolean onLongClick(View v) { clickListener.onItemLongClick(getAdapterPosition(), v); return false; } } public void setOnItemClickListener(ClickListener clickListener) { PasswordAdapter.clickListener = clickListener; } public interface ClickListener { void onItemClick(int position, View v); void onItemLongClick(int position, View v); } }

Luego, dentro del fragmento o actividad, simplemente pulsa:

PasswordAdapter mAdapter = ...; mAdapter.setOnItemClickListener(new PasswordAdapter.ClickListener() { @Override public void onItemClick(int position, View v) { Log.d(TAG, "onItemClick position: " + position); } @Override public void onItemLongClick(int position, View v) { Log.d(TAG, "onItemLongClick pos = " + position); } });


Puede implementar OnClickListener en su clase ViewHolder

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public Item item @InjectView(R.id.tv_title) public TextView tvTitle; @InjectView(R.id.rl_row) public RelativeLayout rlRow; public ViewHolder(View v) { super(v); ButterKnife.inject(this, v); v.setOnClickListener(this); } @Override public void onClick(View view) { Log.e("item title",item.getTitle()); } }

Y onBindViewHolder establece el elemento del titular de su vista

public void onBindViewHolder(ViewHolder holder, int position) { holder.tvTitle.setText(objects.get(position).getTitle()); holder.item = objects.get(position); }


Puede pasar un clickListener al Adapter .

En tu Activity :

private View.OnClickListener mItemClick = new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = null; int position = list.getChildPosition(v); switch (position) { case 0: intent = new Intent(MainActivity.this, LeakCanaryActivity.class); break; case 1: intent = new Intent(MainActivity.this, ButterKnifeFragmentActivity.class); break; } if (intent != null) { MainActivity.this.startActivity(intent); } } };

Luego pásalo al Adapter :

MainAdapter mainAdapter = new MainAdapter(this, mItemClick);

En el Adapter onCreateViewHolder Adapter :

@Override public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) { View itemView = activity.getLayoutInflater().inflate(R.layout.main_adapter_item, viewGroup, false); ViewHolder holder = new ViewHolder(itemView); itemView.setOnClickListener(mItemClick); return holder; }


Tengo una buena solución para onItemClickListener de onItemClickListener para los artículos y subelementos

Paso 1- Crear una interfaz

public interface OnRecyclerViewItemClickListener { /** * Called when any item with in recyclerview or any item with in item * clicked * * @param position * The position of the item * @param id * The id of the view which is clicked with in the item or * -1 if the item itself clicked */ public void onRecyclerViewItemClicked(int position, int id); }

Paso 2- Luego, utilícelo en el método onBindViewHolder del adaptador de la siguiente manera

/** * Custom created method for Setting the item click listener for the items and items with in items * @param listener OnRecyclerViewItemClickListener */ public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) { this.listener = listener; } @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { // viewHolder.albumBg.setBackgroundResource(_itemData[position] // .getImageUrl()); viewHolder.albumName.setText(arrayList.get(position).getName()); viewHolder.artistName.setText(arrayList.get(position).getArtistName()); String imgUrl = arrayList.get(position).getThumbImageUrl(); makeImageRequest(imgUrl, viewHolder); viewHolder.parentView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onRecyclerViewItemClicked(position, -1); } }); viewHolder.settingButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onRecyclerViewItemClicked(position, v.getId()); } }); } // class to hold a reference to each item of RecyclerView public static class ViewHolder extends RecyclerView.ViewHolder { public TextView albumName, artistName; public ImageView albumIcon, settingButton; public LinearLayout parentView; public ViewHolder(View itemLayoutView) { super(itemLayoutView); // albumBg = (LinearLayout) itemLayoutView // .findViewById(R.id.albumDlbg); albumName = (TextView) itemLayoutView.findViewById(R.id.albumName); artistName = (TextView) itemLayoutView .findViewById(R.id.artistName); albumIcon = (ImageView) itemLayoutView.findViewById(R.id.albumIcon); parentView = (LinearLayout) itemLayoutView .findViewById(R.id.albumDlbg); settingButton = (ImageView) itemLayoutView .findViewById(R.id.settingBtn); } }

Paso 3: encuentre y configure la vista del reciclador en la actividad o el fragmento donde está usando esto

recyclerView = (RecyclerView) rootview.findViewById(R.id.vmtopsongs); lm = new LinearLayoutManager(mActivity); lm.setOrientation(LinearLayoutManager.VERTICAL); recyclerView.setLayoutManager(lm); recyclerView.addItemDecoration( new HorizontalDividerItemDecoration.Builder(getActivity()) .paint(Utils.getPaint()).build()); PopularSongsadapter mAdapter = new PopularSongsadapter(gallery, mActivity, true); // set adapter recyclerView.setAdapter(mAdapter); mAdapter.setOnItemClickListener(this); // set item animator to DefaultAnimator recyclerView.setItemAnimator(new DefaultItemAnimator());

Paso 4- Finalmente, implemente la interfaz en la actividad o el fragmento donde está utilizando recyclerview

@Override public void onRecyclerViewItemClicked(int position, int id) { if(id==-1){ Toast.makeText(mActivity, "complete item clicked", Toast.LENGTH_LONG).show(); }else{ Toast.makeText(mActivity, "setting button clicked", Toast.LENGTH_LONG).show(); } }


Aquí está mi fragmento de código

v.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { int newposition = MainActivity.mRecyclerView.getChildAdapterPosition(v); Intent cardViewIntent = new Intent(c, in.itechvalley.cardviewexample.MainActivityCards.class); cardViewIntent.putExtra("Position", newposition); c.startActivity(cardViewIntent); } });

ves vista desdeonCreateViewHolder

ces contexto


Esto es lo que hago para reutilizar. OnClickListener

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyviewHolder> implements View.OnClickListener

en ViewHoder Tomar padre de itemlayout

public class MyviewHolder extends RecyclerView.ViewHolder { LinearLayout linearLayout_item; public MyviewHolder(View itemView) { super(itemView); linearLayout_item=itemView.findViewById(R.id.linearLayout_item); } }

en onBindViewHolder establecer etiqueta como posición

@Override public void onBindViewHolder(MyviewHolder holder, int position) { holder.linearLayout_item.setTag(position); holder.linearLayout_item.setOnClickListener(this); }

y en onclick

@Override public void onClick(View v) { int position = (int) v.getTag(); switch (v.getId()) { case R.id.linearLayout_item: // do some thing with position break; } }


Para mí, esta es la mejor manera:

class YourRecyclerAdapter extends RecyclerView.Adapter<ContactViewHolder> implements View.OnClickListener { ... @Override public void onClick(View view) { int itemPosition = vRecycle.getChildPosition(view); //And use itemPosition to get the item from your collection. This way you dont restrain the ViewHolder with a OnClick callback } ... }


Para mí, la forma más limpia de hacerlo es esta.

  • Constructor adaptador

    `clase privada EnvironmentTypeRecyclerViewAdapter extiende RecyclerView.Adapter {

    private final EnvironmentTypeRecyclerViewAdapterListener mEnvironmentTypeRecyclerViewAdapterListener; private List<Environment> mEnvironmentsData; public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public ViewHolder(View v) { super(v); v.setOnClickListener(this); } @Override public void onClick(View v) { Environment environment = mEnvironmentsData.get(getAdapterPosition()); if (mEnvironmentTypeRecyclerViewAdapterListener != null && environment != null) { mEnvironmentTypeRecyclerViewAdapterListener.onListItemSelected(environment); } } } public EnvironmentTypeRecyclerViewAdapter(List<SmallCellEnvironment> environments, EnvironmentTypeRecyclerViewAdapterListener environmentTypeRecyclerViewAdapterListener) { mEnvironmentTypeRecyclerViewAdapterListener = environmentTypeRecyclerViewAdapterListener; mEnvironmentsData = environments; }`

La interfaz enlazada

private interface EnvironmentTypeRecyclerViewAdapterListener { void onListItemSelected(Environment environment); }


Todas las respuestas publicadas hasta ahora son excelentes soluciones; sin embargo, si no desea lidiar con demasiados detalles de implementación y desea que funcione de manera similar a como lo hace ListView, le recomendaría usar TwoWay-View, como se ve aquí:

https://github.com/lucasr/twoway-view

Tenga en cuenta que esta implementación también admite la pulsación prolongada de elementos, así como la compatibilidad con estados presionados (lo cual es algo importante de lo que carecen otras soluciones a esta pregunta).

Si no desea utilizar toda la biblioteca, eche un vistazo a la clase ClickItemTouchListener , que puede usarse como independiente si es necesario. El único problema que encontré con él en este momento es con una pulsación larga + desplazamiento, parece tener un comportamiento incorrecto.


Aquí está lo que hice. Lea más y descargue la esencia aquí.

Añadiendo lo mismo aquí.

CustomItemClickListener.java

public interface CustomItemClickListener { public void onItemClick(View v, int position); }

ItemsListAdapter.java

public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> { ArrayList<ItemListSingleItem> data; Context mContext; CustomItemClickListener listener; @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false); final ViewHolder mViewHolder = new ViewHolder(mView); mView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onItemClick(v, mViewHolder.getPosition()); } }); return mViewHolder; } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.itemTitle.setText(Html.fromHtml(data.get(position).getTitle())); if (!TextUtils.isEmpty(data.get(position).getThumbnailURL())) { // I Love picasso library :) http://square.github.io/picasso/ Picasso.with(mContext).load(data.get(position).getThumbnailURL()).error(R.drawable.ic_no_image). placeholder(R.drawable.ic_no_image). transform(new RoundedCornersTransformation(5, 0)). into(holder.thumbnailImage); } else { holder.thumbnailImage.setImageResource(R.drawable.ic_no_image); } } @Override public int getItemCount() { return data.size(); } public ItemsListAdapter(Context mContext, ArrayList<ItemsListSingleItem> data, CustomItemClickListener listener) { this.data = data; this.mContext = mContext; this.listener = listener; } public static class ViewHolder extends RecyclerView.ViewHolder { public TextView itemTitle; public ImageView thumbnailImage; ViewHolder(View v) { super(v); itemTitle = (TextView) v .findViewById(R.id.post_title); thumbnailImage = (ImageView) v.findViewById(R.id.post_thumb_image); } } }


De la mayoría de las respuestas anteriores, parece que están configurando sus onclicklisteners para elementos individuales. Sin embargo, la solución que estoy a punto de ofrecer es muy simple pero no intuitiva para muchos. Muchos se olvidan de que los otros componentes están siempre en un componente principal que se usa para mostrar elementos en las vistas de Lista o Reciclador. Esta solución solo consiste en configurar un único escucha de clic en esta vista principal y se juega el turno. La solución también incluye una forma de pasar la posición del elemento al que se hace clic en la lista o en la vista de reciclador. Aquí, nuestro principal rootview es un CardView de la biblioteca de soporte de Android. Aquí está el código de muestra

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> { public static final String LOG_TAG = ListAdapter.class.getSimpleName(); private Cursor mDataset; private Context mContext; private ViewHolder mViewHolder; // Provide a suitable constructor (depends on the kind of dataset) public ListAdapter(Context context, Cursor Dataset) { mDataset = Dataset; mContext = context; } // Create new views (invoked by the layout manager) @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.list_business_view, parent, false); mViewHolder = new ViewHolder(v); return mViewHolder; } public void setData(Cursor newdata) { this.mDataset = newdata; } // Replace the contents of a view (invoked by the layout manager) @Override public void onBindViewHolder(ViewHolder holder, int position) { //Bind data to other items here. To save time, i have ommited that. //here is where we attach a click listerner for an item in the recycler list rather than for each element of a given item. holder.card.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(mContext, " Just cliked item at position " + itemPosition, Toast.LENGTH_LONG).show(); } }); } } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { if (null != mDataset) { return mDataset.getCount(); } return 0; } // Provide a reference to the views for each data item // Complex data items may need more than one view per item, and // you provide access to all the views for a data item in a view holder public static class ViewHolder extends RecyclerView.ViewHolder{ // each data item is just a string in this case public final TextView mBusinesssName; // View for the business name public final TextView mBusinessCategory; //View for the category name public final ImageView businessImage; // View for the business category image Image public final TextView mBusinessDistance; // View for the distance public final CardView card; public ViewHolder(View view) { super(view); mBusinesssName = (TextView) view.findViewById(R.id.list_item_name_textview); mBusinessCategory = (TextView) view.findViewById(R.id.list_item_category_textview); mBusinessDistance = (TextView) view.findViewById(R.id.list_item_dist_textview); businessImage = (ImageView) view.findViewById(R.id.list_item_icon); card = (CardView) view.findViewById(R.id.card_view); } } }


El RecyclerViewno tiene OnClickListenery tendrá que implementarlo nosotros mismos.

Me gusta agregar una OnItemClickListenerinterfaz Adaptercon un onClickmétodo invocado al hacer clic en la vista del elemento desde ViewHolder. Por lo tanto, la responsabilidad de administrar el clic en un elemento está fuera de ViewHoldery Adapter. Será la actividad o fragmento el que decidirá qué hacer.

Agregue una interfaz al oyente y al objeto de escucha.

public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> { ... private static OnItemClickListener onItemClickListener; ... public static interface OnItemClickListener { public void onItemClick(View view, int position); } ... }

Capturamos el clic de la vista raíz del elemento y, cuando se activa la devolución de onClickllamada, el receptor escucha la llamada.

public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> { ... private static OnItemClickListener onItemClickListener; ... public static interface OnItemClickListener { public void onItemClick(View view, int position); } ... public static class ViewHolder extends RecyclerView.ViewHolder { public ImageView imageView; public ViewHolder(View itemRootView) { super(itemRootView); imageView = (ImageView) itemRootView.findViewById(R.id.itemImage); itemRootView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int position = ViewHolder.super.getAdapterPosition(); onItemClickListener.onItemClick(view,position); } }); } } }

Dado que la actividad o el fragmento, fragmento en nuestro caso, asignamos un oyente al adaptador y a la devolución de llamada onClick obtendremos el elemento seleccionado por posición y abriremos una actividad detallada del elemento.

public class ItemsFragment extends Fragment { ... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ... ((ItemsAdapter) adapter).setOnItemClickListener(new ItemsAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { //Do something when an item has been clicked } }); ... } ... }


Implementación de Kotlin de answer de :

mRecyclerView.addOnItemTouchListener(object : RecyclerItemClickListener(this, mRecyclerView,object :RecyclerItemClickListener.OnItemClickListener{ override fun onItemClick(view: View, position: Int) { } override fun onLongItemClick(view: View?, position: Int) { } }){})

RecyclerItemClickListener.java:

import android.content.Context import android.support.v7.widget.RecyclerView import android.view.GestureDetector import android.view.MotionEvent import android.view.View open class RecyclerItemClickListener(context: Context, recyclerView: RecyclerView, private val mListener: OnItemClickListener?) : RecyclerView.OnItemTouchListener { private var mGestureDetector: GestureDetector interface OnItemClickListener { fun onItemClick(view: View, position: Int) fun onLongItemClick(view: View?, position: Int) } init { mGestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() { override fun onSingleTapUp(e: MotionEvent): Boolean { return true } override fun onLongPress(e: MotionEvent) { val child = recyclerView.findChildViewUnder(e.x, e.y) if (child != null && mListener != null) { mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child)) } } }) } override fun onInterceptTouchEvent(view: RecyclerView, e: MotionEvent): Boolean { val childView = view.findChildViewUnder(e.x, e.y) if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { mListener.onItemClick(childView, view.getChildAdapterPosition(childView)) return true } return false } override fun onTouchEvent(view: RecyclerView, motionEvent: MotionEvent) {} override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} }


Lamentablemente RecyclerViewfaltan un par de características que ListViewtenía incorporadas. Por ejemplo, la capacidad de agregar un OnItemClickListenerque se activa cuando se hace clic en un elemento. RecyclerViewle permite configurar un OnClickListeneren su adaptador, pero pasar el detector de clics desde su código de llamada, al adaptador y al ViewHolder, es complicado para capturar un simple clic de elemento.

public class ItemClickSupport { private final RecyclerView mRecyclerView; private OnItemClickListener mOnItemClickListener; private OnItemLongClickListener mOnItemLongClickListener; private View.OnClickListener mOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { if (mOnItemClickListener != null) { RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v); mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v); } } }; private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (mOnItemLongClickListener != null) { RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v); return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v); } return false; } }; private RecyclerView.OnChildAttachStateChangeListener mAttachListener = new RecyclerView.OnChildAttachStateChangeListener() { @Override public void onChildViewAttachedToWindow(View view) { if (mOnItemClickListener != null) { view.setOnClickListener(mOnClickListener); } if (mOnItemLongClickListener != null) { view.setOnLongClickListener(mOnLongClickListener); } } @Override public void onChildViewDetachedFromWindow(View view) { } }; private ItemClickSupport(RecyclerView recyclerView) { mRecyclerView = recyclerView; mRecyclerView.setTag(R.id.item_click_support, this); mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener); } public static ItemClickSupport addTo(RecyclerView view) { ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support); if (support == null) { support = new ItemClickSupport(view); } return support; } public static ItemClickSupport removeFrom(RecyclerView view) { ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support); if (support != null) { support.detach(view); } return support; } public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) { mOnItemClickListener = listener; return this; } public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) { mOnItemLongClickListener = listener; return this; } private void detach(RecyclerView view) { view.removeOnChildAttachStateChangeListener(mAttachListener); view.setTag(R.id.item_click_support, null); } public interface OnItemClickListener { void onItemClicked(RecyclerView recyclerView, int position, View v); } public interface OnItemLongClickListener { boolean onItemLongClicked(RecyclerView recyclerView, int position, View v); } }

También necesitas definir R.id.item_click_supportusando ids.xml:

<?xml version="1.0" encoding="utf-8"?> <resources> <item name="item_click_support" type="id" /> </resources>

El código resultante de escucha de clic ahora se ve así:

ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() { @Override public void onItemClicked(RecyclerView recyclerView, int position, View v) { // do it } });

Para una breve explicación de los clics de recyclerview, eche un vistazo a este littlerobots_blog


Si desea capturar el evento de clic en los elementos individuales, simplemente implemente OnClickListeneren ViewHolderclase y luego establezca escuchas de clic en vistas individuales o en conjunto itemView.

El siguiente ejemplo muestra lo mismo

public class ContactViewHolder extends RecyclerView.ViewHolder implements OnClickListener { TextView txt_title,txt_name,txt_email; public ContactViewHolder(View itemView) { super(itemView); txt_title = (TextView)itemView.findViewById(R.id.txt_title); txt_name = (TextView)itemView.findViewById(R.id.txt_name); txt_email = (TextView)itemView.findViewById(R.id.txt_email); txt_name.setOnClickListener(this); txt_email.setOnClickListener(this); itemView.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub if(v == itemView) { Toast.makeText(RecyclerDemoActivity.this, "Visiting Card Clicked is ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show(); } if(v == txt_name) { Toast.makeText(RecyclerDemoActivity.this, "Name ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show(); } if(v == txt_email) { Toast.makeText(RecyclerDemoActivity.this, "Email ==>"+txt_email.getText(), Toast.LENGTH_SHORT).show(); } } } }


Soy consciente de que hay muchas respuestas, pero pensé que podría proporcionar mi implementación también. (Los detalles completos se pueden encontrar en otra pregunta que respondí ).

Por lo tanto, para agregar un detector de clics, su ViewHolderclase interna debe implementar View.OnClickListener. Esto se debe a que va a configurar una OnClickListeneral itemViewparámetro de la ViewHolder''s constructor. Déjame mostrarte lo que quiero decir:

public class ExampleClickViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { TextView text1, text2; ExampleClickViewHolder(View itemView) { super(itemView); // we do this because we want to check when an item has been clicked: itemView.setOnClickListener(this); // now, like before, we assign our View variables title = (TextView) itemView.findViewById(R.id.text1); subtitle = (TextView) itemView.findViewById(R.id.text2); } @Override public void onClick(View v) { // The user may not set a click listener for list items, in which case our listener // will be null, so we need to check for this if (mOnEntryClickListener != null) { mOnEntryClickListener.onEntryClick(v, getLayoutPosition()); } } }

Las únicas otras cosas que necesita agregar son una interfaz personalizada para su Adaptery un método de establecimiento:

private OnEntryClickListener mOnEntryClickListener; public interface OnEntryClickListener { void onEntryClick(View view, int position); } public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) { mOnEntryClickListener = onEntryClickListener; }

Así que tu nuevo soporte de clics Adapterestá completo.

Ahora, vamos a usarlo ...

ExampleClickAdapter clickAdapter = new ExampleClickAdapter(yourObjects); clickAdapter.setOnEntryClickListener(new ExampleClickAdapter.OnEntryClickListener() { @Override public void onEntryClick(View view, int position) { // stuff that will happen when a list item is clicked } });

Básicamente, es la forma en que configuraría un sistema normal Adapter, excepto que utiliza el método de establecimiento que creó para controlar lo que hará cuando su usuario haga clic en un elemento de la lista en particular.

También puedes ver un conjunto de ejemplos que hice en este Gist en GitHub:

https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07


puede definir fácilmente setOnClickListener en su clase de ViewHolder de la siguiente manera:

public class ViewHolder extends RecyclerView.ViewHolder { TextView product_name; ViewHolder(View itemView) { super(itemView); product_name = (TextView) itemView.findViewById(R.id.product_name); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int itemPosition = getLayoutPosition(); Toast.makeText(getApplicationContext(), itemPosition + ":" + String.valueOf(product_name.getText()), Toast.LENGTH_SHORT).show(); } }); } }