Cómo utilizar OnClickListner en CardView en un RecyclerView?
Intento hacer algo como esto:
Mi problema y cuando hago clic en mi ImageView
, mi CardView
se expande, pero el n-th CardView
también se expande que toma el CardView
ampliado en el que hice clic. No entiendo por qué mi método onClick
también se aplica al otro CardView
.
- Android NestedScrollView alinear el contenido en la parte superior
- ¿Cómo agregar atributos de CardView al tema de la aplicación?
- CardView va encima de FrameLayout, pero declaró primero
- AsyncTask cargando la imagen RecyclerView
- Cardview no respeta el orden del índice z en el diseño relativo
Mi adaptador
public class CardsViewAdapter extends RecyclerView.Adapter<CardsViewAdapter.ViewHolder> { private Game[] mDataset; int rotationAngle = 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 TextView mTextView; public ImageView imageView; public LinearLayout test2; public TextView test3; boolean isPopupVisible; public ViewHolder(View v) { super(v); mTextView = (TextView) v.findViewById(R.id.text_cards); imageView = (ImageView) v.findViewById(R.id.item_description_game_more); test2 = (LinearLayout) v.findViewById(R.id.popup_layout); test3 = (TextView) v.findViewById(R.id.test_view); isPopupVisible = false; } } // Provide a suitable constructor (depends on the kind of dataset) public CardsViewAdapter(Game[] myDataset) { mDataset = myDataset; } // Create new views (invoked by the layout manager) @Override public CardsViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.cards_resume_game, 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, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element //TODO : complete final int pos = position; holder.mTextView.setText(String.valueOf(mDataset[position].getId_game())); holder.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("POS","actual pos = "+pos); holder.test3.setText("Position : "+pos); // Perform action on click if (holder.isPopupVisible) { holder.isPopupVisible = false; ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180); anim.setDuration(500); anim.start(); rotationAngle += 180; rotationAngle = rotationAngle%360; CardsAnimationHelper.collapse(holder.test2); } else { holder.isPopupVisible = true; ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180); anim.setDuration(500); anim.start(); rotationAngle += 180; rotationAngle = rotationAngle%360; CardsAnimationHelper.expand(holder.test2); } } }); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.length; } }
- ¿Por qué CardView y RecyclerView requieren minSdkVersion L?
- setOnClickListener en un TextView dentro de un Cardview
- Android Resalte la tarjeta como modal de diálogo dentro de recyclerview en clic
- ColorDrawable no se puede convertir en android.support.v7.widget.RoundRectDrawableWithShadow
- Error: (27) No se encontró ningún identificador de recurso para el atributo 'srcCompat' en el paquete 'com.example.jaisonjoseph.newsclient'
- Deje que un aspecto de vista de tarjeta deshabilitado - ¿Hay un aspecto predeterminado / preferido?
- Establecimiento de elevación en XML en AppCompat CardView en Android 5.0
- Cardview inmovilizado gris subrayado (dispositivos Android 4.0.4)
Creo que ya tienes tu clase de Game
. Simplemente agregue un atributo nuevo en esa clase llamada expanded
.
public Class Game { public int id; public String description; // Add an extra attribute to track the checked status // By default, set the checked status to false public boolean expanded = false; }
Ahora, ya que ahora tiene un atributo para realizar un seguimiento del estado expandido, puede hacer fácilmente algo como esto.
@Override public void onBindViewHolder(final ViewHolder holder, int position) { final int pos = position; holder.mTextView.setText(String.valueOf(mDataset[position].id)); // Set the expanded or collapsed mode here if(mDataset[position].expanded) expandView(holder.test2); else collapseView(holder.test2); // Now set the onClickListener like this holder.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { holder.test3.setText("Position : "+pos); // Animate the imageView here animateImageView(holder.imageView); // Toggle the expanded attribute value if(mDataset[position].expanded) mDataset[position].expanded = false; else mDataset[position].expanded = true; // Now call notifyDataSetChanged to make the change to effect refreshList(); } }); } // Extra functions inside your adapter class to improve readability private void collapseView(View view) { CardsAnimationHelper.collapse(view); } private void expandView(View view) { CardsAnimationHelper.expand(view); } private void animateImageView(ImageView imageView) { ObjectAnimator anim = ObjectAnimator.ofFloat(imageView, "rotation",rotationAngle, rotationAngle + 180); anim.setDuration(animationDuration); anim.start(); rotationAngle += 180; rotationAngle = rotationAngle % 360; } long animationDuration = 500; private void refreshList() { final Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { notifyDataSetChanged(); } }, animationDuration); }
La razón por la que esto sucede es porque el n-ésimo elemento de su lista está reutilizando la vista que expandió. Eso es lo que el titular de la vista es, para reutilizar las vistas y no crearlas cada vez.
Para que usted pueda arreglar que asegúrese de comprobar el estado expandido de su vista enBindViewHolder de nuevo y no sólo onClick.
Agregue PopupVisible a su clase de juego como una variable y en onBindViewHolder expandió el cardview sólo cuando game.getPopupVisible es true:
public class CardsViewAdapter extends RecyclerView.Adapter<CardsViewAdapter.ViewHolder> { private Game[] mDataset; int rotationAngle = 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 TextView mTextView; public ImageView imageView; public LinearLayout test2; public TextView test3; public ViewHolder(View v) { super(v); mTextView = (TextView) v.findViewById(R.id.text_cards); imageView = (ImageView) v.findViewById(R.id.item_description_game_more); test2 = (LinearLayout) v.findViewById(R.id.popup_layout); test3 = (TextView) v.findViewById(R.id.test_view); } } // Provide a suitable constructor (depends on the kind of dataset) public CardsViewAdapter(Game[] myDataset) { mDataset = myDataset; } // Create new views (invoked by the layout manager) @Override public CardsViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // create a new view View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.cards_resume_game, 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, int position) { // - get element from your dataset at this position // - replace the contents of the view with that element //TODO : complete final int pos = position; Game game=mDataset[position]; holder.mTextView.setText(String.valueOf(mDataset[position].getId_game())); if (game.getPopupVisible()) { ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180); anim.setDuration(500); anim.start(); rotationAngle += 180; rotationAngle = rotationAngle%360; CardsAnimationHelper.collapse(holder.test2);} else.... holder.imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("POS","actual pos = "+pos); holder.test3.setText("Position : "+pos); // Perform action on click if (game.getPopupVisible()) { game.setPopupVisible(false); ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180); anim.setDuration(500); anim.start(); rotationAngle += 180; rotationAngle = rotationAngle%360; CardsAnimationHelper.collapse(holder.test2); } else { game.setPopupVisible(true); ObjectAnimator anim = ObjectAnimator.ofFloat(v, "rotation",rotationAngle, rotationAngle + 180); anim.setDuration(500); anim.start(); rotationAngle += 180; rotationAngle = rotationAngle%360; CardsAnimationHelper.expand(holder.test2); } } }); } // Return the size of your dataset (invoked by the layout manager) @Override public int getItemCount() { return mDataset.length; } }
- Recibe UDP en Android Marshmallow
- Android: ¿por qué google lugares api volver lugares en otros países, incluso cuando los límites es de 500 metros?