Android y Material Design
Francisco Manuel López Jurado Colaboraciones 30/09/2016
En este primer post sobre Android y Material Design crearemos una aplicación usando los últimos componentes que se añadieron con el lanzamiento de Lollipop (API 21). Iremos detallando cada componente con una pequeña descripción inicial, cómo incluirlos en nuestro proyecto y qué puede aportarnos en nuestra app.
Sin más, ¡comencemos!
ToolBar
Se trata de una mejora considerable del anterior ActionBar, hasta incluso se puede añadir como uno propio haciendo uso del método setActionBar(). Es muy recomendable que todas nuestras Activity extiendan de AppCompatActivity para utilizarlo.
Uso
Es un elemento que nos aporta un título para nuestras pantallas, un botón de back, distintas acciones a realizar, etc. Por lo que es de suma importancia tener claro que este es uno de los elementos más importantes añadidos en esta versión de la API.
Añadirlo a nuestro código
Una vez creado el proyecto nos dirigimos a la Activity principal (MainActivity.class) y comprobamos que extienda de AppCompatActivity.
Actualmente, al crear un proyecto el ActionBar aparece por defecto y si queremos sustituirlo por la Toolbar tenemos que modificar el tema de nuestra app en styles.xml para que extienda por ejemplo de:Theme.AppCompat.Light.NoActionBar
Para incluirlo simplemente haremos uso de esta porción de código y añadiéndolo a nuestro layout de la activity.
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" />
Si queremos reutilizar la misma Toolbar entre todas Activity debemos crear unt llamado app_bar.xml y hacer un include en todos los layouts que la necesitemos. Posteriormente la usaremos de la siguiente forma:
android:layout_height="match_parent" />
A la hora de hacerle referencia en el código solo tenemos que hacer esto:
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
FloatingActionButton (FAB)
Este componente no deja de ser un mero botón pero con varias características y es que aparte de ser flotante (no depende de otros elementos), se le puede añadir una propiedad llamada “Elevation” que le da esa sensación de profundidad al modificar el eje Z.
Uso
El FAB es un botón que debe tener la funcionalidad más directa para un usuario. Con él ganamos en usabilidad disminuyendo en gran cantidad los clicks para esta función.
Añadirlo a nuestro código
No es más que añadir el XML siguiente en el layout que queramos usar:
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
Y después solo tenemos que añadirle el listener para indicarle qué acción debe hacer cuando se haga click sobre él. Quedando tal que así:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO:
}
});
RecyclerView
Se trata de una nueva forma de crear un listado de elementos y tiene un objetivo muy claro, acabar con los antiguos ListView y GridView unificándolos en un mismo componente.
Añadirlo a nuestro código
Para añadir RecyclerView tenemos que seguir estos pasos:
-
Agregar las dependencias de Gradle
compile 'com.android.support:cardview-v7:21.0.+'
compile 'com.android.support:recyclerview-v7:21.0.+'
-
Añadir el componente a nuestro layout quedando nuestro XML así:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main" tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
-
Una vez que ya lo tenemos en nuestro XML, ahora necesitamos hacer una referencia desde nuestra activity.
mRVItems = (RecyclerView)findViewById(R.id.my_recycler_view);
mRVItems.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mRVItems.setLayoutManager(mLayoutManager);
Una vez realizados los pasos anteriores vamos a seguir con la creación de nuestro Adapter.
RecyclerView.Adapter y ViewHolder
La función básica del adapter es la de contener todos los datos que serán mostrados en un listado de elementos, pero tenemos un problema:
¿Qué ocurre cuando tenemos 1000 elementos? ¿Qué hacemos con las vistas que consumirán esos elementos?
Anteriormente teníamos que implementar un patrón para la reutilización de vistas llamado ViewHolder, por lo que cada vez que creábamos un Adapter teníamos que copiar y pegar la misma porción de código que implementaba dicho patrón y modificarlo según las especificaciones de cada uno. Pero con la llegada de este nuevo adapter, esto se ha acabado ya que nos aporta dicho patrón implementado por defecto y nosotros solo tenemos que dar forma a los métodos que nos pide.
Uso
Siempre que usemos un RecyclerView tenemos que usar este adapter.
Añadirlo a nuestro código
Pasos para crear un CustomAdapter:
-
Creamos una clase java con el nombre CustomAdapter y hacemos que extienda de RecyclerView.Adapter.
-
Creamos dos variables privadas:
-
private List mDataset = new ArrayList<>(); //Se trata de una lista con los elementos a mostrar
-
private CustomItemClickListener mCustomItemClickListener; // Es una interfaz propia para capturar cuando se haya hecho click sobre un elemento de la lista.
-
Creamos el constructor de nuestro ViewHolder en el que tenemos que pasarle una vista y luego hacer las referencias a los elementos dentro de la misma.
-
Creamos la interfaz CustomItemClickListener con el método onItemClicked que no devolverá nada y que nos dará el elemento sobre el que hemos hecho click.
-
Tenemos varios métodos que hay que sobre escribir que son:
-
onCreateViewHolder, este método es el encargado de crear la vista y enlazarla con nuestro ViewHolder. Sólo es llamado la primera vez que se crea el adapter.
-
onBindViewHolder, este método se llama cada vez que se crea o reutiliza una celda de la lista y lo usamos para poner los valores de cada elemento del dataset.
-
getItemCount, este método es usado para saber cuántos elementos tiene nuestro adapter. Siempre hay que devolver el tamaño de nuestro dataset.
-
Una vez que los hemos implementado solo tenemos que crear nuestro adapter y unirlo a nuestro RecyclerView.
CustomAdapter adapter = new CustomAdapter(mDataset, new CustomAdapter.CustomItemClickListener() {
@Override
public void onItemClicked(ModelAndroidVersion itemClicked) {
//TODO: añadir la implementación necesaria
}
});mRVItems.setAdapter(adapter);
Todo el código referente a este apartado se encuentra en CustomAdapter.java en el repositorio indicado al final del post.
CardView
Se trata de un componente que nos aporta facilidades para crear una vista con bordes redondeados y una sombra dependiendo de la elevación que le demos.
Añadirlo a nuestro código
Simplemente tenemos que incluirlo en nuestro layout como si se tratase de un simple LinerLayout o RelativeLayout tal que así:
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="8dp"
android:elevation="10dp"
card_view:cardCornerRadius="8dp">
Dentro del mismo podemos colocar todas las vistas que queramos.
Picasso
Se trata de una librería para la carga asíncrona de imágenes y nos facilita mucho el trabajo. Podrás encontrar más información en su web.
Añadirlo a nuestro código
Para cargar una imagen en un ImageView, los pasos a seguir son:
-
Picasso.with(this), donde le pasamos el contexto de nuestra aplicación.
-
.load(urlDeLaImagen), se le pasa una url, fichero, etc de la imagen que queramos cargar.
-
.into(target), necesitamos pasarle el elemento donde finalmente se cargará la imagen.
-
Finalmente quedaría tal que así:
Picasso.with(this).load(mCurrentModelAndroidVersion.getUrl()).into(mIVLogo)
Palette
Este componente nos proporciona una herramienta muy útil para sacar todo tipo de información de la imagen que le pasamos como parámetro (en forma de bitmap).
Uso
Este componente es muy interesante de estudiar a fondo ya que puede conseguir una “armonía” de colores en nuestra aplicación, haciéndola muy atractiva a la vista del usuario.
Añadirlo a nuestro código
-
Incluimos en el build.gradle la librería de Palette:
compile 'com.android.support:palette-v7:23.1.1'
-
Para usar esta librería tenemos que pasarle un Bitmap y generar un objeto de tipo Palette:
Palette palette = Palette.from(bitmap).generate();
Después de esto sólo tenemos que acceder a los parámetros que necesitemos.
Los distintos colores que nos devuelven son:
-
Vibrant
-
Vibrant Light
-
Vibrant Dark
-
Muted
-
Muted Light
-
Muted Dark
Todo el código del proyecto se encuentra en:
https://github.com/franlopjur/BetaBeersDemo
Espero que te haya gustado y si tienes alguna pregunta, aportación o quieres que amplíe algo, puedes dejarme un comentario.