Screen Shot 2015-08-04 at 9.20.42 AM.png

Material Design es una guía exhaustiva para diseño visual, de movimiento e interacción en diversas plataformas y dispositivos. En este codelab aprenderás los principios de este lenguaje de diseño, mientras construyes una app Android.

Lo que aprenderás

- Temas y colores para crear superficies tangibles y diseño similar al editorial.

- Mejores prácticas para estructurar elementos visuales y mejorar la navegación.

- Animación y retroalimentación táctil para expresar movimiento con significado.

Requerimientos

* puedes utilizar dispositivos Android corriendo Android 2.3.3 (Gingerbread, API Level 10) o mayores, sin embargo, algunos efectos de Material Design, como el efecto de ola, no serán visibles en dispositivos con Android 4.4 (KitKat) o anteriores.

Descarga la app de ejemplo

Puedes descargar todo el código de ejemplo a tu computadora...

Descargar archivo Zip

...o clonar el repositorio de GitHub con el siguiente comando en la terminal:

$ git clone https://github.com/googlecodelabs/android-design-library.git

Ejecuta la aplicación

Primero, veamos cómo luce la versión final de la app. Con el código que descargaste, sigue las siguientes instrucciones para abrir la app en Android Studio.

  1. Importa el paquete completo de android-design-library.
  1. Selecciona el directorio android_studio_folder.png1-Base del folder con el código de ejemplo (Quickstart > Import Project... > 1-Base).
  2. Haz click en el botón gradlesync.pngGradle sync.
  3. Activa 'USB debugging' en tu dispositivo Android.
  4. Conecta tu dispositivo Android y haz click en el botónexecute.pngRun. Verás la pantalla de inicio aparecer en unos segundos.

Preguntas frecuentes

Veremos dos características fundamentales del diseño material: ¡temas y colores!

Los temas te permiten aplicar un tono consistente a una app y los desarrolladores pueden escoger entre temas claro y oscuro (ver Figuras 1 y 2).

Screen Shot 2015-08-11 at 5.24.37 PM.png

También puedes definir colores personalizados utilizando atributos de Theme, que son utilizados de manera automática por la app para diferentes componentes, p. ej. colorPrimaryDark para la barra de estado y colorPrimary para la barra de app (ver Figura 3).

Screen Shot 2015-08-11 at 5.39.40 PM.png

  1. Añade el tema Light a tu app y personaliza algunos de los colores en res/values/styles.xml

styles.xml

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#3F51B5</item>
        <!-- Light Indigo -->
        <item name="colorPrimaryDark">#3949AB</item>
        <!-- Dark Indigo -->
        <item name="colorAccent">#00B0FF</item>
        <!-- Blue -->
    </style>
    <style name="AppTheme" parent="AppTheme.Base"></style>
</resources>

Tu app debe lucir así:

Screenshot_20150921-121011.png

En este paso crearás el esqueleto básico de una app, a la que podrás incorporar componentes de diseño material más adelante.

Screenshot_20150924-154133.png

Agrega un Toolbar

Estás lista(o) para construir encima de tu proyecto de inicio.

  1. Añade un Toolbar y Tabs a tu app activity_main.xml y MainActivity.java
  2. Borra TextView y añade Toolbar en activity_main.xml

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

</RelativeLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // Adding Toolbar to Main screen
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

Añade Tabs al Toolbar

  1. En activity_main.xml borra RelativeLayout y sustitúyelo con CoordinatorLayout.
  2. En activity_main.xml agrega un elemento Tablayout dentro de AppBarLayout.
  3. En MainActivity.java crea la clase tabs e infla los menús.

activity_main.xml

<android.support.design.widget.CoordinatorLayout 
        android:id="@+id/main_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:layout_scrollFlags="scroll|enterAlways"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

            <android.support.design.widget.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </android.support.design.widget.AppBarLayout>
    </android.support.design.widget.CoordinatorLayout>

MainActivity.java

TabLayout tabs = (TabLayout) findViewById(R.id.tabs);
tabs.addTab(tabs.newTab().setText("Tab 1"));
tabs.addTab(tabs.newTab().setText("Tab 2"));
tabs.addTab(tabs.newTab().setText("Tab 3"));

Tu app debe lucir como esta:

Screenshot_20150923-165129.png

Añade un Fragment y un ViewPager

Ahora vamos a agregar vistas individuales a cada Tab, de tal suerte que verás distintas interfaces gráficas cuando cambias de tab.

  1. Crea un archivo llamado recycler_view.xml en el folder res/layout.

recycler_view.xml

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:paddingBottom="@dimen/md_keylines"
    android:paddingTop="@dimen/md_keylines"
    android:scrollbars="vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
  1. Crea 3 clases Java del tipo Fragmento: listContentFragment.java, TileContentFragment.java y CardContentFragment.java.
  2. En el archivo MainActivity.java crea una variable de tipo ViewPager y un Adapter para que el contenido sea desplazable.
  3. En el archivo activity_main.xml añade un elemento ViewPager afuera de AppBarLayout.
  4. Crea un archivo definiendo el acomodo de cada vista item_list.xml, item_tile.xml e item_card.xml en res/layout/. Echa un vistazo a los atributos individuales y observa que personalizaciones están disponibles.

Ahora tu app debe lucir así:

Screenshot_20150923-174747.png

RecyclerView es un contenedor para desplegar conjuntos de datos grandes eficientemente al mantener en pantalla un número limitado de views. Nuestro conjunto de datos para este codelab se compone de tarjetas vacías, que son piezas de papel que sirven como punto de entrada para más información.

Agrega ahora un RecyclerView a tu app:

  1. Agrega las dependencias a build.gradle para usar CardView y RecyclerView.

build.gradle

dependencies {
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:design:23.0.1'
    compile 'com.android.support:cardview-v7:23.0.1'
    compile 'com.android.support:recyclerview-v7:23.0.1'
}
  1. En cada fragmento, crea y personaliza el RecyclerView añadiendo componentes utilizando la vista definida en el RecyclerView.Adapter.

Ahora tu app debe lucir así:

Screenshot_20151008-171028.png

Le agregamos diseño a cada vista modificando los archivos item_list.xml, item_tile.xml, e item_card.xml; para que cada vista tenga imágenes como contenido visual.

Ahora tu app debe lucir así:

Screenshot_20151008-173707.png

Agregando un NavigationDrawer

El NavigationDrawer se desliza de la izquierda. Es un patrón común en las apps de Google y sigue los lineamientos y métricas para listar elementos.

  1. Crea un archivo llamado menu_navigation.xml que defina los elementos de navegación en la carpeta res/menu.

menu_navigation.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:icon="@drawable/ic_home_black_24dp"
            android:tint="@color/button_grey"
            android:title="One" />
        <item
            android:icon="@drawable/ic_favorite_black_24dp"
            android:tint="@color/button_grey"
            android:title="Two" />
        <item
            android:icon="@drawable/ic_bookmark_border_black_24dp"
            android:tint="@color/button_grey"
            android:title="Three" />
    </group>
</menu>
  1. Crea el archivo llamado navheader.xml que defina un NavigationDrawer en la carpeta res/layout/.
  2. En activity_main.xml:
  1. Encapsula todos los componentes dentro de DrawerLayout el cuál permite vistas interactivas del cajón que salen desde la orilla de la ventana.
  2. Añade una vista del tipo NavigationView afuera de CoordinatorLayout.

activty_main.xml

<android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/navheader"
        app:menu="@menu/menu_navigation" />
  1. En la clase MainActivity.java:
  1. Añade la siguiente variable de instancia en MainActivity:
private DrawerLayout mDrawerLayout;
  1. Añade el siguiente código al método onCreate de MainActivity.java para inicializar la variable de NavigationDrawer.
// Create Navigation drawer and inflate layout
        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
        // Adding menu icon to Toolbar
        ActionBar supportActionBar = getSupportActionBar();
        if (supportActionBar != null) {
            supportActionBar.setHomeAsUpIndicator(R.drawable.ic_menu_white_24dp);
            supportActionBar.setDisplayHomeAsUpEnabled(true);
        }
        // Set behavior of Navigation drawer
        navigationView.setNavigationItemSelectedListener(
                new NavigationView.OnNavigationItemSelectedListener() {
                    // This method will trigger on item Click of navigation menu
                    @Override
                    public boolean onNavigationItemSelected(MenuItem menuItem) {
                        // Set item in checked state
                        menuItem.setChecked(true);

                        // TODO: handle navigation

                        // Closing drawer on item click
                        mDrawerLayout.closeDrawers();
                        return true;
                    }
                });
  1. Añade mDrawerLayout.openDrawer(GravityCompat.START); a la clase MainActivity.java para hacer que el NavigationDrawer se mueva cuando tocas el menú.
int id = item.getItemId();
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        } 
         //adding following code to open drawer 
         else if (id == android.R.id.home) {
            mDrawerLayout.openDrawer(GravityCompat.START);
        }
        return super.onOptionsItemSelected(item);

Añade un FloatingActionButton (FAB) y despliega un SnackBar

Los FloatingActionButton se utilizan para acciones relevantes y se distinguen con un ícono de círculo que flota encima de la IU.

Vamos a crear un FAB que despliega un SnackBar que dará retroalimentación acerca de la interacción del botón y mostrar un mensaje corto:

  1. En el archivo activity_main.xml añade un FloatingActionButton al final del componente CoordinatorLayout.
  2. En el archivo MainActivity.java, añade al FAB un Listener del tipo OnClick que despliega un SnackBar.

activty_main.xml

<android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right|bottom"
            android:layout_marginBottom="@dimen/md_keylines"
            android:layout_marginRight="@dimen/md_keylines"
            android:src="@drawable/ic_add_white_24dp" />

MainActivity.java

// Adding Floating Action Button to bottom right of main view
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Snackbar.make(v, "Hello Snackbar!",
                        Snackbar.LENGTH_LONG).show();
            }
        });
  1. En la carpeta values-21 agrega un archivo llamado styles.xml para crear una barra de sistema transparente para dispositivos que corran Android 5 o superior.

styles.xml

<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>
  1. En el archivoCardContentFragment.java agrega métodos para mostrar un SnackBar cuando los botones dentro de las Cards sean presionados.

Ahora tu app debe lucir así:

md-codelab01.png

Crea una View de Detalle

Utiliza un Intent para permitir al usuario moverse entre tarjetas y vistas detalladas. Es momento de crear un View de Detalle en nuestra app:

  1. Crea una clase llamada DetailActivity.java y otro llamado activity_detail.xml.
  2. Crea un nuevo objeto Intent dentro de cada ListContentFragment.java, TileContentFragment.java, y CardContentFragment.java de forma tal que cada elemento tenga una liga a la vista detallada.
public static class ViewHolder extends RecyclerView.ViewHolder {

        public ViewHolder(LayoutInflater inflater, ViewGroup parent) {
            super(inflater.inflate(R.layout.item_list, parent, false));
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Context context = v.getContext();
                    Intent intent = new Intent(context, DetailActivity.class);
                    context.startActivity(intent);
                }
            });
        }
    }
  1. Para que tu actividad se muestre, asegúrate de agregar el componente activity al archivo de configuración AndroidManifest.xml.

AndroidManifest.xml

<activity
            android:name=".DetailActivity"
            android:parentActivityName=".MainActivity">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".MainActivity" />
        </activity>

Un CollapsingToolbar ofrece transiciones visuales al compactar el Toolbar conforme el usuario se desplaza hacia abajo en tu app. Ahora vamos a agregar un CollapsingToolbar:

  1. En el archivo activity_detail.xml, agrega un componente de tipo AppBarLayout y CollapsingToolbarLayout dentro de CoordinatorLayout.
  2. En el archivo DetailActivity.java asigna el CollapsingToolbar y el título de la vista detallada.

DetailActivity.java

// Set Collapsing Toolbar layout to the screen
        CollapsingToolbarLayout collapsingToolbar =
                (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
        // Set title of Detail page
        collapsingToolbar.setTitle(getString(R.string.item_title));

Estás lista(o) para crear una app con Material Design.

Qué cubrimos

Siguientes pasos

Ahora es el momento para agregar Material Design a tus apps.

Para saber más

project-end.png