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.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.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 |
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.
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.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.
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.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.
No hay comentarios:
Publicar un comentario