Blog para desarrollo de aplicaciones en Android, aprende paso a paso como crear aplicaciones.

Usamos cookies propias y de terceros que entre otras cosas recogen datos sobre sus hábitos de navegación para mostrarle publicidad personalizada y realizar análisis de uso de nuestro sitio.
Si continúa navegando consideramos que acepta su uso. OK Más información | Y más

Como crear RecyclerView Swipe en Android

Android Swipe Example

Hola amigos continuamos con este curso de aplicaciones Android y les traemos este control practico para nuestras aplicaciones podrán implementarlo como quieran para el uso de ListView.

Como crear RecyclerView Swipe en Android

Crear Proyecto Android (Aquí)

Vamos a crear un proyecto para el ejemplo de nuestra aplicación. Cuando la tengamos lista podemos proseguir en los siguientes pasos.

Diseño de Aplicación Swipe

Comenzaremos creando el diseño de nuestra aplicación nos vamos a dirigir a la ruta de nuestro archivo Res y en nuestra main_activity añadiremos el siguiente control.

Como crear Swipe en Android
Abrir archivo activity_main para añadir control RecyclerView

<android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerSwipe"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:layout_margin="10dp"
        android:overScrollMode="never" />

Si llegan a tener problemas con el RecyclerView pueden añadiré la referencia al modulo del control.

Agregar las dependencias de nuestro control RecyclerView

Como crear Swipe en Android
Diseño de nuestro RecyclerView

Ahora le daremos a Sync y esperamos que nuestro proyecto se compile para generar las dependencias en nuestra aplicación.

Una vez teniendo listo esto vamos a añadir un nuevo archivo xml. al cual nombraremos item_row.
Como crear Swipe en Android
Añadiremos el archivo item_row para nuestro RecyclerView

Vamos a agregar los siguientes controles a nuestro archivo creado, nos quedara de la siguiente forma.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    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:focusable="true"
    android:clickable="true"
    android:layout_margin="8dp"
    android:background="?android:attr/selectableItemBackground">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp">

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/nombre"
                android:textSize="16sp"
                android:textStyle="bold"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:text="Sergio Godoy"/>

            <TextView
                android:id="@+id/nacionalidad"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAlignment="textEnd"
                tools:text="Hondureño" />

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/equipo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:text="Real España"/>

        </LinearLayout>

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Edad: "/>

            <TextView
                android:id="@+id/edad"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                tools:text="26"/>

            <TextView
                android:id="@+id/calificacion"
                android:textSize="20sp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAlignment="textEnd"
                tools:text="07" />
        </LinearLayout>
    </LinearLayout>

</android.support.v7.widget.CardView>

El diseño nos quedaría de la siguiente forma.

Código de Aplicación Swipe.

Para continuar con esta aplicación ya teniendo lista la parte del diseño vamos a seguir añadiendo las clases que componen este ejemplo del control Swipe.

Agregamos la clase a la cual nombraremos como usuario.

Agregaremos la clase para controlar los objetos de nuestro RecyclerView Swipe
public class usuario {

    private String Nombre, Nacionalidad, Equipo;
    private int Calificacion, Edad;

    public String getNombre() {
        return Nombre;
    }

    public void setNombre(String Nombre) {
        this.Nombre = Nombre;
    }

    public String getNacionalidad() {
        return Nacionalidad;
    }

    public void setNacionalidad(String Nacionalidad) {
        this.Nacionalidad = Nacionalidad;
    }

    public String getEquipo() {
        return Equipo;
    }

    public void setEquipo(String Equipo) {
        this.Equipo = Equipo;
    }

    public Integer getCalificacion() {
        return Calificacion;
    }

    public void setCalificacion(Integer Calificacion) {
        this.Calificacion = Calificacion;
    }

    public Integer getEdad() {
        return Edad;
    }

    public void setEdad(Integer Edad) {
        this.Edad = Edad;
    }
}

Ahora añadiremos una clase muy importante que es el Adaptador para añadir los elementos de los controles independientes a nuestro RecyclerView Swipe el cual es un control compuesto.

Agregamos la clase Adaptador para nuestros controles que se añadiran al RecyclerView Swipe


import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;

class UsuarioDataAdapter extends RecyclerView.Adapter<UsuarioDataAdapter.UsuarioViewHolder> {
    public List<usuario> Usuarios;

    public class UsuarioViewHolder extends RecyclerView.ViewHolder {
        // Declaramos las variables para nuestros controles
        private TextView name, nationality, club, rating, age;

        public UsuarioViewHolder(View view) {
            super(view);
            // Hacemos la declaracion de las variables a los objetos en el item_row
            name = (TextView) view.findViewById(R.id.nombre);
            nationality = (TextView) view.findViewById(R.id.nacionalidad);
            club = (TextView) view.findViewById(R.id.equipo);
            rating = (TextView) view.findViewById(R.id.calificacion);
            age = (TextView) view.findViewById(R.id.edad);
        }
    }

    public UsuarioDataAdapter(List<usuario> Usuarios) {
        this.Usuarios= Usuarios;
    }

    @Override
    public UsuarioViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // Control View que hace referencia al item_row
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_row, parent, false);

        return new UsuarioViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(UsuarioViewHolder holder, int position) {
        // Recupera los valores y los asigna a los controles que seran retornados a nuestro RecyclerView Swipe
        usuario usuario = usuario.get(position);
        holder.name.setText(usuario.getNombre());
        holder.nationality.setText(usuario.getNacionalidad());
        holder.club.setText(usuario.getEquipo());
        holder.rating.setText(usuario.getCalificacion().toString());
        holder.age.setText(usuario.getEdad().toString());
    }

    @Override
    public int getItemCount() {
        return Usuarios.size();
    }
}

Ahora añadiremos las clases que son importantes para el efecto de este ejemplo utilizando el RecyclerView Swipe.

Clase SwipeControllerActions para RecyclerView Swipe
public abstract class SwipeControllerActions {
    public void onLeftClicked(int position) {}

    public void onRightClicked(int position) {}
}
Y la siguiente clase.
Como crear Swipe en Android
Agregaremos la clase SwipeController que manipulara el Touch en nuestro RecyclerView Swipe


import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper.Callback;
import android.view.MotionEvent;
import android.view.View;
import static android.support.v7.widget.helper.ItemTouchHelper.*;

enum ButtonsState {
    GONE,
    LEFT_VISIBLE,
    RIGHT_VISIBLE
}

class SwipeController extends Callback {
    private boolean swipeBack = false;
    private ButtonsState buttonShowedState = ButtonsState.GONE;
    private RectF buttonInstance = null;
    private RecyclerView.ViewHolder currentItemViewHolder = null;
    private SwipeControllerActions buttonsActions = null;
    private static final float buttonWidth = 300;

    public SwipeController(SwipeControllerActions buttonsActions) {
        this.buttonsActions = buttonsActions;
    }

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        return makeMovementFlags(0, LEFT | RIGHT);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    }

    @Override
    public int convertToAbsoluteDirection(int flags, int layoutDirection) {
        if (swipeBack) {
            swipeBack = buttonShowedState != ButtonsState.GONE;
            return 0;
        }
        return super.convertToAbsoluteDirection(flags, layoutDirection);
    }

    @Override
    public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
        if (actionState == ACTION_STATE_SWIPE) {
            if (buttonShowedState != ButtonsState.GONE) {
                if (buttonShowedState == ButtonsState.LEFT_VISIBLE) dX = Math.max(dX, buttonWidth);
                if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) dX = Math.min(dX, -buttonWidth);
                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            }
            else {
                setTouchListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            }
        }

        if (buttonShowedState == ButtonsState.GONE) {
            super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
        }
        currentItemViewHolder = viewHolder;
    }

    private void setTouchListener(final Canvas c, final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder, final float dX, final float dY, final int actionState, final boolean isCurrentlyActive) {
        recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                swipeBack = event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP;
                if (swipeBack) {
                    if (dX < -buttonWidth) buttonShowedState = ButtonsState.RIGHT_VISIBLE;
                    else if (dX > buttonWidth) buttonShowedState  = ButtonsState.LEFT_VISIBLE;

                    if (buttonShowedState != ButtonsState.GONE) {
                        setTouchDownListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
                        setItemsClickable(recyclerView, false);
                    }
                }
                return false;
            }
        });
    }

    private void setTouchDownListener(final Canvas c, final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder, final float dX, final float dY, final int actionState, final boolean isCurrentlyActive) {
        recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    setTouchUpListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
                }
                return false;
            }
        });
    }

    private void setTouchUpListener(final Canvas c, final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder, final float dX, final float dY, final int actionState, final boolean isCurrentlyActive) {
        recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    SwipeController.super.onChildDraw(c, recyclerView, viewHolder, 0F, dY, actionState, isCurrentlyActive);
                    recyclerView.setOnTouchListener(new View.OnTouchListener() {
                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                            return false;
                        }
                    });
                    setItemsClickable(recyclerView, true);
                    swipeBack = false;
                    // Maneja los eventos de click en los controles
                    if (buttonsActions != null && buttonInstance != null && buttonInstance.contains(event.getX(), event.getY())) {
                        if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
                            buttonsActions.onLeftClicked(viewHolder.getAdapterPosition());
                        }
                        else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
                            buttonsActions.onRightClicked(viewHolder.getAdapterPosition());
                        }
                    }
                    buttonShowedState = ButtonsState.GONE;
                    currentItemViewHolder = null;
                }
                return false;
            }
        });
    }

    private void setItemsClickable(RecyclerView recyclerView, boolean isClickable) {
        for (int i = 0; i < recyclerView.getChildCount(); ++i) {
            recyclerView.getChildAt(i).setClickable(isClickable);
        }
    }

    private void drawButtons(Canvas c, RecyclerView.ViewHolder viewHolder) {
        float buttonWidthWithoutPadding = buttonWidth - 20;
        float corners = 16;
        // Declaramos la variable que proyecta el View de nuestro control
        View itemView = viewHolder.itemView;
        Paint p = new Paint();
        // Dibuja el boton de la izquierda de nuestro RecyclerView Swipe
        RectF leftButton = new RectF(itemView.getLeft(), itemView.getTop(), itemView.getLeft() + buttonWidthWithoutPadding, itemView.getBottom());
        p.setColor(Color.BLUE);
        c.drawRoundRect(leftButton, corners, corners, p);
        drawText("EDITAR", c, leftButton, p);
        // Dibuja el control de la derecha de nuestro RecyclerView Swipe
        RectF rightButton = new RectF(itemView.getRight() - buttonWidthWithoutPadding, itemView.getTop(), itemView.getRight(), itemView.getBottom());
        p.setColor(Color.RED);
        c.drawRoundRect(rightButton, corners, corners, p);
        drawText("ELIMINAR", c, rightButton, p);
        // Variable que maneja los estados de nuestros controles
        buttonInstance = null;
        if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
            buttonInstance = leftButton;
        }
        else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
            buttonInstance = rightButton;
        }
    }
    // Clase que dibuja los controles
    private void drawText(String text, Canvas c, RectF button, Paint p) {
        float textSize = 60;
        p.setColor(Color.WHITE);
        p.setAntiAlias(true);
        p.setTextSize(textSize);

        float textWidth = p.measureText(text);
        c.drawText(text, button.centerX()-(textWidth/2), button.centerY()+(textSize/2), p);
    }

    public void onDraw(Canvas c) {
        if (currentItemViewHolder != null) {
            drawButtons(c, currentItemViewHolder);
        }
    }

}

Ahora añadiremos a nuestro MainActivity el siguiente código para completar este ejemplo.
import android.graphics.Canvas;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    // Declaramos las variables que utilizaremos
    private UsuarioDataAdapter mAdapter;
    SwipeController swipeController = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Clases para inicializar el contenido y las funciones de nuestra aplicación
        setUsuarioDataAdapter();
        setupRecyclerView();
    }

    private void setUsuarioDataAdapter() {
        // Declaramos la lista de nuestra clase usuario
        List<usuario> usuarios = new ArrayList<>();
        try {
            // Vamos a dar lectura a nuestro archivo usuarios.csv
            InputStreamReader is = new InputStreamReader(getAssets().open("usuarios.csv"));

            BufferedReader reader = new BufferedReader(is);
            reader.readLine();
            String line;
            String[] st;
            // Ciclo que va leer las posiciones de nuestro archivo
            while ((line = reader.readLine()) != null) {
                st = line.split(",");
                usuario itemUsuarios = new usuario();
                itemUsuarios.setNombre(st[0]);
                itemUsuarios.setNacionalidad(st[1]);
                itemUsuarios.setEquipo(st[4]);
                itemUsuarios.setCalificacion(Integer.parseInt(st[9]));
                itemUsuarios.setEdad(Integer.parseInt(st[14]));
                usuarios.add(itemUsuarios);
            }
        } catch (IOException e) {

        }
        // Añadimos el contenido leido de nuestro archivo a nuestro adaptador
        mAdapter = new UsuarioDataAdapter(usuarios);
    }

    private void setupRecyclerView() {
        // Declaramos la variable que hace referencia a nuestro RecyclerView
        RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerSwipe);

        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        recyclerView.setAdapter(mAdapter);
        // Controla el evento para remover un item de nuestra lista
        swipeController = new SwipeController(new SwipeControllerActions() {
            @Override
            public void onRightClicked(int position) {
                mAdapter.Usuarios.remove(position);
                mAdapter.notifyItemRemoved(position);
                mAdapter.notifyItemRangeChanged(position, mAdapter.getItemCount());
            }
        });
       
        ItemTouchHelper itemTouchhelper = new ItemTouchHelper(swipeController);
        itemTouchhelper.attachToRecyclerView(recyclerView);

        recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
                swipeController.onDraw(c);
            }
        });
    }
}


Y para finalizar nuestra aplicación añadiremos el archivo de usuarios.cvs vamos a dar click en nuestra aplicación.

Como crear RecyclerView Swipe en Android
Esto nos añadira la carpeta de Assests. donde pegaremos nuestro archivo usuarios.csv

Descargar archivo usuarios.cvs (Aquí)

Crear Emulador AVD (Aquí)

Vamos a crear nuestro emulador para ejecutar nuestra aplicación RecyclerView Swipe.

Como crear RecyclerView Swipe en Android
Como crear RecyclerView Swipe en Android
Como crear RecyclerView Swipe en Android
Y este seria el resultado de nuestra aplicación.

Cualquier duda que tenga pueden dejarnos su comentario y pueden aplicar este ejemplo para sus aplicaciones.

Curso Kotlin Español

No hay comentarios:

Publicar un comentario

x

Registrate!

Curso Android Español

Curso Kotlin Español

eBook Free Android Studio

Noticias y Eventos

¡Directamente a tu INBOX!

Le enviaremos nuestros recursos gratis. Para obtener nuestro contenido nuevo, únase a nuestra comunidad. No te molestaremos enviando información inútil. ¡No te pierdas ninguna actualización, mantente conectado! Recuerda verificar tu correo electronico.

Ingrese su dirección de correo electrónico:

Entregado por FeedBurner