RecyclerView Deslice con una vista inferior
He estado haciendo algunas investigaciones y todavía tengo que encontrar un ejemplo o implementación que le permite poner una vista (Ejemplo de la imagen debajo) debajo de la RecyclerView cuando pase. ¿Alguien tiene algún ejemplo o una idea de cómo se implementaría sin utilizar una biblioteca.
Aquí es cómo estoy implementando el golpe para descartar.
- Utilice ItemTouchHelper para deslizar-a-despedir con otra vista que se muestra detrás del barrido hacia fuera
- RecyclerView eliminar el bug de animación
- ¿Cómo pasar datos a fragmentos cuando haga clic en cardview en onBindViewHolder?
- Cómo poner RecyclerView dentro de NestedScrollView?
- Número escalonado de columnas del número dinámico del gestor de diseño de cuadrícula
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { return false; } @Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { return super.getSwipeDirs(recyclerView, viewHolder); } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { if (viewHolder instanceof ViewDividers) { Log.e("DIRECTION", direction + ""); } } }; new ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(recycler);
Aquí está el ejemplo de la bandeja de entrada de Google:
- Selección de elementos de fila de reciclaje
- Android - RecyclerView espaciado entre elementos en una cuadrícula
- ¿Cómo mostrar el número exacto de elementos en RecyclerView?
- Ocultar / Mostrar barra de herramientas de forma programática en CoordinatorLayout
- Animación RecyclerView no funciona
- Recycler View con múltiples filas y columnas - AutoFit como Flow Layout
- ¿Cuál es la diferencia entre el método swapadapter y el método notifydatasetchanged en la vista Recycler?
- Obtener el elemento visible en el centro de RecycleView al desplazarse
Mi comprensión de cómo se hace esto es que uno pondría dos vistas en el xml que se mostraría por línea en su recyclerview.
Así por ejemplo, este sería mi adaptador:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public static class ExampleViewHolder extends RecyclerView.ViewHolder { public TextView background; public TextView foreground; public ExampleViewHolder(View v) { super(v); background = (TextView) v.findViewById(R.id.background); foreground = (TextView) v.findViewById(R.id.foreground); } @Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { if (holder instanceof ExampleViewHolder) { ((ExampleViewHolder) holder).background.setBackgroundColor(); // do your manipulation of background and foreground here. } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()) .inflate(R.layout.example, parent, false); return new ExampleViewHolder(v); } } }
Cada línea en el reciclerview está tirando del diseño xml de R.layout.example. Por lo tanto, para crear una vista debajo, sólo puede usar relativelayout o framelayout para crear las vistas una encima de la otra:
<RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/background" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/foreground"/> </RelativeLayout>
Entonces si usted no quiere utilizar una biblioteca para el golpe, usted puede copiar esta clase de google y posteriormente modificado por Bruno Romeu Nunes:
La clase requerirá que usted cree un oyente del golpe:
swipeTouchListener = new SwipeableRecyclerViewTouchListener(mRecyclerView, new SwipeableRecyclerViewTouchListener.SwipeListener() { @Override public boolean canSwipe(int position) { if (position == totalPost.size() - 1 && !connected) { return false; } return true; } @Override public void onDismissedBySwipeLeft(RecyclerView recyclerView, int[] reverseSortedPositions) { for (int position : reverseSortedPositions) { //change some data if you swipe left } myAdapter.notifyDataSetChanged(); } @Override public void onDismissedBySwipeRight(RecyclerView recyclerView, int[] reverseSortedPositions) { for (int position : reverseSortedPositions) { //change some data if you swipe right } myAdapter.notifyDataSetChanged(); } });
A continuación, simplemente vincularlo con su recyclerview:
mRecyclerView.addOnItemTouchListener(swipeTouchListener);
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.
Me gusta el enfoque @erik, pero yo recomendaría dibujar lo que quieras a través de Canvas pasó a la función onChildDraw (). Por ejemplo, fondo de elemento o icono.
@Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { final ColorDrawable background = new ColorDrawable(Color.RED); background.setBounds(0, itemView.getTop(), itemView.getLeft() + dX, itemView.getBottom()); background.draw(c); super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); }
En este enfoque, se dibujará lo que se necesita a petición y no hay necesidad de inflar vistas no utilizadas
Puede utilizar la biblioteca RvTools . Le ayudará a implementar fácilmente lo que desea.
Basta con crear su SwipeContextMenuDrawer con el aspecto deseado
public class YourSwipeContextMenuDrawer extends SwipeContextMenuDrawer { private final Paint mRightPaint; private final Paint mIconPaint; private final Bitmap mRightIconBitmap; public YourSwipeContextMenuDrawer(@NonNull Context context) { mRightPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mRightPaint.setColor(ContextCompat.getColor(context, R.color.deep_orange_400)); mRightIconBitmap = GraphicUtils.getBitmap(context, R.drawable.ic_delete, 100, 100); mIconPaint = new Paint(); mIconPaint.setColorFilter(new PorterDuffColorFilter(ContextCompat.getColor(context, R.color.backgroundColor), PorterDuff.Mode.SRC_IN)); } @Override public void drawRight(@NonNull Canvas canvas, @NonNull View view) { canvas.drawRect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), mRightPaint); canvas.drawBitmap(mRightIconBitmap, view.getLeft() + mRightIconBitmap.getWidth() - 20, (view.getBottom() + view.getTop() - mRightIconBitmap.getHeight()) >> 1, mIconPaint); } @Override public void drawLeft(@NonNull Canvas canvas, @NonNull View view) { } }
Y crea la instancia de RvTools con la acción del deslizar y desliza el cajón del menú del contexto como esto
new RvTools.Builder(recyclerView) .withSwipeRightAction(this) .withSwipeContextMenuDrawer(new YourSwipeContextMenuDrawer(getContext())) .buildAndApplyToRecyclerView();
Solución simple sin asignación o dibujo sobre lienzo. SomeAdapter.SomeVH
debe contener vista superior y bajo vista. Y con este enfoque podremos deslizar sólo la vista superior (contenedor), exponiendo bajo vista (con etiqueta, icono lo que quieras)
class SomeTouchHelper extends ItemTouchHelper.Callback { ... @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { if (viewHolder instanceof SomeAdapter.SomeVH) { SomeAdapter.SomeVH someViewHolder = (SomeAdapter.SomeVH) viewHolder; ViewCompat.setTranslationX(someViewHolder.mContainer, dX); } } else { super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } } ... }
No olvide restaurar el estado de vista inicial de SomeVH
en el adaptador onViewRecycled ()
- Cómo utilizar el argumento LIMIT en una consulta SQLite con Android
- ¿Cómo forzar a EditText a aceptar sólo números?