Intoducción a Material Design con librerías de soporte

  • ¿Que es Material Design?
  • AppCompat Theme
  • Widgets
    • Snackbar
    • Floating Action Button
    • App Bar y Toolbar
    • TabLayout
    • Navigation View
    • TextInputLayout
    • Coordinator Layout
    • AppCompat Dialogs

Contenido

¿Que es Material Design?

Material design es un concepto, una filosofía, unas pautas enfocadas al diseño utilizado en Android, pero también en la web y en cualquier plataforma.
En esta filosofa está basado el theme Material que utiliza Android Lollipop

Especificación de Material Design por google:
https://www.google.com/design/spec/material-design/introduction.html

AppCompat Theme

El theme AppCompat es un tema que nos permite aplicar la base de Material Design a dispositivos pre-Lollipop

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <item name="colorAccent">@color/accent_material_dark</item>
        <item name="android:windowActionBar">false</item>
        <item name="windowNoTitle">true</item>

    </style>

Widgets

Las nuevas librerías de soporte nos permiten hacer uso de nuevos componentes de lollipop en versiones anteriores de  Android

La snackbar se utilizan para darle feedback a un usuario sobre una operación mostrando un breve mensaje en la parte inferior de la pantalla, las snackbars tambien pueden contener acciones

SnackBar

SnackBar

Snackbar
  .make(parentLayout, R.string.snackbar_text, Snackbar.LENGTH_LONG)
  .setAction(R.string.snackbar_action, myOnClickListener)
  .show();

Floating Action Button (FAB)

El FAB se utiliza para representar la acción primaria en una pantalla.

<android.support.design.widget.FloatingActionButton
        android:src="@drawable/ic_done"
        app:fabSize="normal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

Los valores del fabSize pueden ser "normal" y "mini". Como sugiere su nombre es el tamaño de nuestro FAB

Toolbars y Appbars

Las appbar/toolbas son el reemplazo a las Actionbars.

 

La diferencia principal con la actionbar es que la toolbar es parte de la activity y no de la ventana como los es la actionbar, lo cual nos da mas libertad a la hora de darles estilos

Toolbars y Appbars

Para utilizar una Toolbar debemos de darle a nuestra app un tema sin action bar 

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- ...and here we setting appcompat’s color theming attrs -->
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <item name="colorAccent">@color/accent_material_dark</item>
        <item name="android:windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="drawerArrowStyle">@style/MyDrawerArrowToggle</item>
    </style>

Toolbars y Appbars

Para que la actionbar sea soportada en versiones viejas de android podemos extender nuestra activity de AppcompatActivty, con esto traemos toda la funcionalidad de las Actionbars a versiones de android mayores o iguales a la API 7.

 

public class MainActivity extends AppCompatActivity

Para utilizar este tipo de activity nuestro tema debe ser Appcopat o similar

Toolbars y Appbars

Agregamos la toolbar al xml de nuestra activty

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

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

   </RelativeLayout>

podemos darle estilo a nuestra toolbar usando el campo theme y popup theme con los ThemeOverlay

Toolbars y Appbars

Agregamos nuestra toolbar como supportActionbar de nuetsra activty

    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            setupToolbar();
    
        }
        private void setupToolbar(){
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
        }
    }

si queremos tener acceso a nuestra Actionbar llamamos al metodo getSupportActionbar() de nuestra Activity

Toolbars y Appbars

Si queremos por ejemplo agregar tabs a nuestra actionbar, ahi utilizamos la toolbar junto al tablayput contenidos en un AppbarLayout

<android.support.design.widget.AppBarLayout

        android:id="@+id/appbarlayout"
        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_height="wrap_content"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

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

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

TabLayout

Con el widget de Tablayout podemos agregar tabs a nuestra toolbar


            <android.support.design.widget.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" /> 
private void setupTablayout(){
        
        tabLayout = (TabLayout) findViewById(R.id.tabLayout);
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
        tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
        tabLayout.addTab(tabLayout.newTab().setText("Tab 4"));
    }

TabLayout

NavigationDrawer y NavigationView 

La libreria de soporte nos da la posibilidad de agregar un navigation drawer a nuestras activities

NavigationDrawer y NavigationView 

Para agregar el navigation drawer en nuestra activity debemos declarar en el xml un DrawerLayout

El Drawer layout debe de tener unicamente dos componentes hijos.
El primero debe de ser el contenido principal de la activity y el segundo el menu de navegación (navigation drawer)

En versiones viejas de la libreria se utilizaba un layout cualquiera como puede ser un Linear layout como layout de navegacion

A partir de la v22 disponemos de un Navigationview, el cual se le puede indicar un layout header y un menu para inflar la opciones de navegación muy similar a los menu de una Actionbar

NavigationDrawer y NavigationView 

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/navigation_header"
        app:itemTextColor="#333"
        app:itemIconTint="#333"
        app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout>

NavigationDrawer y NavigationView 

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/navigation_snackbar"
            android:checked="true"
            android:title="@string/snackbar" />
        <item
            android:id="@+id/navigation_text_input"
            android:title="@string/text_input" />
        <item
            android:id="@+id/navigation_coordinator"
            android:title="@string/coordinator" />
        <item
            android:id="@+id/navigation_tab_layout"
            android:title="@string/tab_layout" />
        <item
            android:id="@+id/navigation_appbar"
            android:title="@string/appbar" />
    </group>
</menu>

menu/drawer

NavigationDrawer y NavigationView 

Integrando el NavigationDrawer junto a la toolbar

public class MainActivity extends AppCompatActivity {

    private ActionBarDrawerToggle mActionBarDrawerToggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
         ...
        setupToolbar();

    }
    private void setupToolbar(){
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Show menu icon
        final ActionBar ab = getSupportActionBar();
        DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        ab.setDisplayHomeAsUpEnabled(true);
        mActionBarDrawerToggle = new ActionBarDrawerToggle
            (this,drawerLayout,toolbar,R.string.drawer_opened,R.string.drawer_closed){
                @Override
                public void onDrawerClosed(View drawerView) {
                    super.onDrawerClosed(drawerView);    
                }    
                @Override
                public void onDrawerOpened(View drawerView) {
                    super.onDrawerOpened(drawerView);    
                }
        };
        drawerLayout.setDrawerListener(mActionBarDrawerToggle);
    }
}

TextInputLayout

El TextInpout layout mejora la presentación de los EditText que tengamos en nuestra app. 

Una de las mejoras es mostrar el hint de nuestro edit text arriba de este cuando hacemos foco en el. 
La otra mejora es el display de mensajes de error

TextInputLayout

setErrorEnabled(true);
setError(getString(R.string.text_error_message));
 <android.support.design.widget.TextInputLayout
        android:id="@+id/til2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/til">        
        <EditText
            android:id="@+id/textDialog2"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:hint="Last Name"/>
    </android.support.design.widget.TextInputLayout>

Coordinator Layout

El aspecto visual es solo una parte de material Design, el movimiento también es una parte importante, desde los efectos de ripple en los eventos touch a las transiciones.
La librería Design incluye un nuevo Layout llamado CoordinatorLayout el cual provee control adicional sobre los eventos touch de las vistas contenidas en dentro del layout alfo que muchos componentes de la librería Design sacan ventaja

Coordinator Layout y CollapsingToolbarLayout

CollapsintToolbarlayout nos permite colapsar nuestra toolbar con los eventos de scroll del contenido de la vista

Estas animaciones no funcionan con el scrollview y con listview 

  • NestedScrollView de la libreria de soporte en lugar del ScrollView
  • RecyclerView en lugar de ListView

Dialogs

import android.support.v7.app.AlertDialog;      

      ///Para alert dialogs

    AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.Base_Theme_AppCompat_Dialog);
    builder.setTitle("AppCompatDialog");
    builder.setMessage("Lorem ipsum dolor...");
    builder.setPositiveButton("OK", null);
    builder.setNegativeButton("Cancel", null);
    builder.show();
    

    //// Para Dialogos customizados 

    Dialog dialog = new AppCompatDialog(this);
        dialog.setTitle(R.string.dialog_title);
        dialog.setContentView(R.layout.dialog_content);
        dialog.show();

Otro de los elemenotos que son actualziados en las librerias de soporte a igualar Material son los AlertDialogs

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <android.support.v4.widget.NestedScrollView android:layout_height="match_parent" android:layout_width="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:text="Large Text"
                android:id="@+id/textView2" />

        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
    <android.support.design.widget.AppBarLayout
        android:layout_height="256dp"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:layout_width="match_parent"
        android:id="@+id/appBarLayout">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="64dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                android:id="@+id/appBarImageView" />
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_height="wrap_content"
                android:layout_width="match_parent"
                android:minHeight="?attr/actionBarSize"
                app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

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

Librerias utilizadas

    com.android.support:appcompat-v7:22.2.0
    com.android.support:design:22.2.0

Sitios de apoyo

 

deck

By mathias de brun