studio recyclerview que oncreateviewholder item imágenes ejemplo dependencia con cardview card and android android-recyclerview

android - recyclerview - oncreateviewholder que es



RecyclerView Desliza con una vista debajo de él (5)

He estado investigando un poco y aún tengo que encontrar un ejemplo o implementación que le permita poner una vista (Imagen de ejemplo a continuación) debajo de RecyclerView cuando desliza. ¿Alguien tiene algún ejemplo o una idea de cómo esto se implementaría SIN usar una biblioteca?

Así es como estoy implementando el deslizamiento para descartar.

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:


Estaba investigando el mismo problema.
Lo que terminé haciendo fue, en el diseño que contenía el recyclerView, agregué un FrameLayout simple llamado ''swipe_bg'' de la misma altura que uno de mis elementos RecyclerView.ViewHolder . Configuré su visibilidad como "ida" y la coloqué debajo de RecyclerView

Luego, en mi actividad donde configuro el ItemTouchHelper , anulo el onChildDraw como tal ...

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 me pareció la forma más sencilla.


Me gusta el enfoque @erik, pero recomendaría dibujar lo que quiera a través de la función canvas aprobada en onChildDraw (). por ejemplo, fondo o ícono del artículo.

@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, dibujará lo que necesite bajo demanda y no será necesario inflar las vistas no utilizadas


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 vista de reciclador.

Entonces, 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 la vista de reciclador está extrayendo el diseño xml de R.layout.example. Por lo tanto, para crear una vista debajo, 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 no quiere usar una biblioteca para deslizar, puede copiar esta clase de google y posteriormente la modifica Bruno Romeu Nunes:

https://github.com/heruoxin/Clip-Stack/blob/master/app/src/main/java/com/catchingnow/tinyclipboardmanager/SwipeableRecyclerViewTouchListener.java

La clase requerirá que crees un oyente de deslizamiento:

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(); } });

Luego simplemente conéctelo con su vista de reciclador:

mRecyclerView.addOnItemTouchListener(swipeTouchListener);


Puede usar la Biblioteca de RvTools . Le ayudará a implementar fácilmente lo que desea.

Simplemente crea tu 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 una instancia de RvTools con la acción de deslizar y desliza el menú contextual del menú como este

new RvTools.Builder(recyclerView) .withSwipeRightAction(this) .withSwipeContextMenuDrawer(new YourSwipeContextMenuDrawer(getContext())) .buildAndApplyToRecyclerView();


Solución simple sin asignación o dibujo en lienzo. SomeAdapter.SomeVH debe contener vista superior y vista inferior. Y con este enfoque, podremos deslizar solo la vista superior (contenedor), exponiendo debajo de la vista (con la etiqueta, el 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 en ViewRecycled ()