Mostrar la vista personalizada bajo el elemento RecyclerView deslizado

En primer lugar, vi esta pregunta: Añadir un fondo de color con el texto / icono bajo fila swiped cuando se utiliza Android RecyclerView

Sin embargo, aunque el título indica "con texto / icono", la respuesta sólo cubre el uso del objeto Canvas para dibujar un rectángulo.

Ahora tengo dibujado un rectángulo verde puesto en práctica; Sin embargo quiero hacer que sea más obvio lo que va a suceder mediante la adición de "hecho" botón, al igual que en la siguiente captura de pantalla.

Introduzca aquí la descripción de la imagen

He creado una vista personalizada:

 public class ChoosePlanView extends LinearLayout{ public ChoosePlanView(Context context) { super(context); init(); } public ChoosePlanView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public ChoosePlanView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init(){ View v = inflate(getContext(), R.layout.choose_plan_view, null); addView(v); } } 

Y el diseño es muy simple, que consiste en fondo verde y el icono:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/choose_green"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/doneIcon" android:layout_gravity="center_horizontal|right" android:src="@mipmap/done"/> </LinearLayout> 

Intenté sobreescribir el método OnChildDraw :

 // ChoosePlanView choosePlanView; <- that was declared and initialized earlier, so I don't have to create a new ChoosePlanView everytime in OnChildDraw(); ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { /* onMove, onSwiped omitted */ public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { View itemView = viewHolder.itemView; if(dX < 0){ choosePlanView.invalidate(); //choosePlanView.setBackgroundResource(R.color.delete_red); choosePlanView.measure(itemView.getWidth(), itemView.getHeight()); choosePlanView.layout(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom()); c.save(); c.translate(choosePlanView.getRight() + (int) dX, viewHolder.getAdapterPosition()*itemView.getHeight()); choosePlanView.draw(c); c.restore(); } super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } } 

Y funciona un poco (dibuja mi ChoosePlanView ), pero hay dos problemas.

En primer lugar dibuja sólo un pequeño cuadrado verde que envuelve mi icono "hecho" (la parte roja de la vista vista en la captura de pantalla de abajo viene de la línea comentada choosePlanView.setBackgroundResource(R.color.delete_red); ). La vista tiene el ancho correcto sin embargo, cuando se registra en depurador.

La segunda cosa es donde se coloca el icono. He especificado que quiero que se centró horizontalmente y siempre "pegado" en el lado derecho de la vista. Sin embargo, se mueve, cuando el elemento de RecyclerView es swiped, y con fondo rojo muestra que no se coloca en el centro tampoco.

Intenté agregar la línea choosePlanView.invalidate() , porque pensé que sucede, porque la visión fue creada anterior, pero parece redibujar no cambia nada.

Introduzca aquí la descripción de la imagen

El uso de la interfaz ItemTouchUiUtil proporciona una solución robusta a esto. Le permite tener una vista en primer plano y fondo en su ViewHolder y delegar todo el manejo de deslizamiento a la vista en primer plano. He aquí un ejemplo que utilizo para desplazar a la derecha para eliminar.

En su ItemTouchHelper.Callback :

 public class ClipItemTouchHelper extends ItemTouchHelper.SimpleCallback { ... @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { if (viewHolder != null){ final View foregroundView = ((ClipViewHolder) viewHolder).clipForeground; getDefaultUIUtil().onSelected(foregroundView); } } @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { final View foregroundView = ((ClipViewHolder) viewHolder).clipForeground; drawBackground(viewHolder, dX, actionState); getDefaultUIUtil().onDraw(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive); } @Override public void onChildDrawOver(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { final View foregroundView = ((ClipViewHolder) viewHolder).clipForeground; drawBackground(viewHolder, dX, actionState); getDefaultUIUtil().onDrawOver(c, recyclerView, foregroundView, dX, dY, actionState, isCurrentlyActive); } @Override public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder){ final View backgroundView = ((ClipViewHolder) viewHolder).clipBackground; final View foregroundView = ((ClipViewHolder) viewHolder).clipForeground; // TODO: should animate out instead. how? backgroundView.setRight(0); getDefaultUIUtil().clearView(foregroundView); } private static void drawBackground(RecyclerView.ViewHolder viewHolder, float dX, int actionState) { final View backgroundView = ((ClipViewHolder) viewHolder).clipBackground; if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { //noinspection NumericCastThatLosesPrecision backgroundView.setRight((int) Math.max(dX, 0)); } } } 

Y en el archivo de diseño, defina las vistas de primer plano y de fondo:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/clipRow" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <View style="@style/Divider"/> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/row_selector" > <RelativeLayout android:id="@+id/clipBackground" android:layout_width="0dp" android:layout_height="match_parent" android:background="@color/swipe_bg" tools:layout_width="match_parent"> <ImageView android:layout_width="32dp" android:layout_height="32dp" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginLeft="12dp" android:layout_marginStart="12dp" android:focusable="false" android:src="@drawable/ic_delete_24dp" tools:ignore="ContentDescription"/> </RelativeLayout> <RelativeLayout android:id="@+id/clipForeground" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/clip_vertical_margin" android:paddingLeft="@dimen/clip_horizontal_margin" android:paddingRight="@dimen/clip_horizontal_margin" android:paddingTop="@dimen/clip_vertical_margin" > <CheckBox android:id="@+id/favCheckBox" android:layout_width="@dimen/view_image_size" android:layout_height="@dimen/view_image_size" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:background="@android:color/transparent" android:button="@drawable/ic_star_outline_24dp" android:clickable="true" android:contentDescription="@string/content_favorite" /> ... </RelativeLayout> </FrameLayout> </LinearLayout> 

En vez de dibujar encima, creo que usted debe utilizar viewType

Implements getItemViewType(int position) en el adaptador, devolviendo diferentes tipos, por ejemplo 0 para normal, 1 para swipped

Y cambiar onCreateViewHolder etc para devolver el diseño diferente en diferentes viewType

Conseguí conseguir esto para trabajar con el color y una imagen ampliando la respuesta proporcionada por Sanvywell en: Añadiendo un fondo coloreado con el texto / el icono debajo de fila frotada al usar el RecyclerView de Androide

No volveré a crear el post completo (puedes seguir el enlace). En pocas palabras, no creé una vista completa para renderizar durante el desplazamiento, pero sólo agregué un mapa de bits al lienzo, colocado adecuadamente en el elemento RecyclerView.

Yo estaba investigando el mismo problema. Lo que acabé haciendo fue, en el diseño que contenía el recyclerView, he añadido un FrameLayout simple llamado 'swipe_bg' de la misma altura que uno de mis elementos de RecyclerView.ViewHolder . Puse su visibilidad a "ido", y la coloqué bajo el RecyclerView

Entonces, en mi actividad donde establecí el ItemTouchHelper , anular el onChildDraw como así ..

 final ItemTouchHelper.SimpleCallback swipeCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT){ @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { View itemView = viewHolder.itemView; swipe_bg.setY(itemView.getTop()); if(isCurrentlyActive) { swipe_bg.setVisibility(View.VISIBLE); }else{ swipe_bg.setVisibility(View.GONE); } super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } }; 

No sé si esa es la mejor manera, pero parecía la forma más sencilla.

  • RecyclerView ItemDecoration Espaciado y Span
  • RecyclerView y solicitudes de fondo con una gran colección de elementos
  • Deslizar para descartar para RecyclerView
  • Recyclerview dentro de la vista de desplazamiento anidada cargando todos los datos en lugar de llamar una por una imagen cuando se desplaza
  • Google Play Store como interfaz utilizando la vista de reciclador
  • Recyclerview lag en desplazamiento debido a los anuncios de Admob
  • Android RecyclerView: notifyDataSetChanged () IllegalStateException
  • Encabezado RecyclerView bajo elementos de Android
  • Pausar un video en un recicladorVer cuando hay un cierto porcentaje en la pantalla
  • RecyclerView java.lang.IndexOutOfBoundsException: Inconsistencia detectada. Posición de elemento no válida cuando se reanuda desde fragmento añadido
  • Android reciclerview notifyItemInserted animación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.