Icono del sitio Develou

Floating Action Button En Android – Material Design

En este artículo ampliaré el uso del Floating Action Button para la promoción de  acciones. Recuerda que este elemento hace parte del estándar Material Design para el nuevo diseño de UI.

Lo primero que aprenderás (o recordarás) será la ubicación de este elemento en un layout. Luego probarás las diferentes posiciones que puede tomar para romper bordes entre elementos. También verás cómo adjuntarle una escucha de eventos,  generarás algunas animaciones y transformar el FAB en una Toolbar.

Floating Action Button En Material Design

Como dice Google en la documentación del Material Design, un float action button es un botón para destacar una acción en tu app. Se caracteriza por tener una forma circular, un icono interno que representa la acción, una reacción de superficie y la capacidad de cambiar de forma, desplazarse e interactuar con otros elementos.

Este viene en dos tamaños: por defecto (56dp) y mini (24dp). El primero se usa para proporcionar acciones generales, el segundo se adapta mejor cuando se necesita un elemento que siga el mismo patrón de orientación de otros componentes.

En java el floating action button se define por la clase FloatingActionButton. En Xml usa la etiqueta <android.support.design.widget.FloatingActionButton> para representar el view dentro de un layout.

Por ejemplo…

<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/margenes_fab"
    android:src="@drawable/icono_agregar" />

Ten en cuenta los siguientes atributos a la hora de usar el FAB:

Floating action button con OnClickListener

Antes de explicar esta parte, crea un nuevo proyecto en Android Studio con las siguientes características:

La plantilla de la actividad en blanco por defecto trae consigo un floating action button en su layout y además implementa una acción de click en el código.

Eventos FAB — Usa la interfaz View.OnClickListener sobre el fab para procesar los eventos de click que se produzcan.

Para relacionar la escucha usa el método setOnClickListener() sobre la instancia del floating action button y sobrescribe el método onClick() con las acciones a ejecutar.

ActividadPrincipal.java

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;

public class ActividadPrincipal extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Se presionó el FAB", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }
}

El anterior código ejecuta una Snackbar para mostrar el mensaje "Se presionó el FAB". Obviamente tu pondrás acciones más complejas cómo iniciar una nueva actividad ó agregar un pago.

Rompimiento de bordes con el floating action button

Romper los bordes con un floating action button es un principio del diseño de layouts en Material Design para la armonización de superficies.

Para lograr este efecto de superposición entre elementos puedes usar layouts especializados en promover capas cómo el FrameLayout o RelativeLayout. Solo debes calcular las márgenes necesarias para acomodarlos.

Otra alternativa es usar el CoordinatorLayout para este fin. Lo importante es tener en consideración los siguientes atributos de elemento:

Por ejemplo…

En una app bar extendida con un tamaño de 200dp puedes romper su borde inferior con un FAB.

Esto se hace asignado el id del contenido de la actividad y denotando el anclaje hacia los bordes superior y derecho, con las constantes top|end.

actividad_principal.xml

<android.support.design.widget.CoordinatorLayout 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"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:toolbarId="@+id/toolbar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/detail_toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

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

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

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/contenedor_detalle_item"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical|start"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/icono_compartir"
        app:layout_anchor="@+id/contenedor_detalle_item"
        app:layout_anchorGravity="top|end" />

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

El resultado de la previsualización sería el siguiente:

Haz de cuenta que el coordinator layout le entrega un poder especial al view que es marcado por app:layout_anchor para que se comporte como referencia absoluta de las posiciones relativas del elemento anclado. En este caso el floating action button.

Si quieres hacer flotar el fab hacia el lado izquierdo, entonces usa start|top para app:layout_anchorGravity.

Animación de escala en el Floating Action Button

El FAB puede variar su comportamiento en las escenas debido a su versatilidad como material flexible. Uno de los casos más frecuente es la variación de su escala al entrar o salir de escena.

Para simular el cambio de escala, usa el método clase AnimationUtils.loadInterpolator() para crear un interpolador que permita controlar los tiempos en animaciones de escala.

En este caso animaré el floating action button para que comience en una escala 0 y termine en su tamaño original al entrar a la escena.

ActividadPrincipal.xml

import android.animation.Animator;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;

public class ActividadPrincipal extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setScaleX(0);
        fab.setScaleY(0);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            final Interpolator interpolador = AnimationUtils.loadInterpolator(getBaseContext(),
                    android.R.interpolator.fast_out_slow_in);

            fab.animate()
                    .scaleX(1)
                    .scaleY(1)
                    .setInterpolator(interpolador)
                    .setDuration(600)
                    .setStartDelay(1000)
                    .setListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            fab.animate()
                                    .scaleY(0)
                                    .scaleX(0)
                                    .setInterpolator(interpolador)
                                    .setDuration(600)
                                    .start();
                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {

                        }
                    });
        }
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Se presionó el FAB", Snackbar.LENGTH_LONG).show();
            }
        });
    }
}

Android proporciona un interpolador prediseñado para el cálculo de aceleración de un movimiento curvo llamado fast_out_slow_in.xml, el cual cargamos con AnimationUtils.

El código anterior sirve en versiones LOLLIPOP en adelante. Si quieres ver animaciones con soporte de versiones anterior, puedes ver el tutorial Working with Android FAB Animations. De verdad es muy útil.

Rotar Floating Action Button Al Clickearlo

Otra animación básica es la rotación del floating action button al clickearlo. Esta se ve muy bien cuando el icono hace referencia a la obtención de más acciones al primer click, y luego rota en forma de x (gesto de cerrar) para revertir el resultado.

Esta vez se usa el método rotate() para girar el componente en el plano XY con respecto a su centro. Especificaré 45 grados para la primera rotación al clickear, y luego se retorna a 0 según el valor de una bandera global.

ActividadPrincipal.xml

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;

public class ActividadPrincipal extends AppCompatActivity {

    boolean click = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setImageResource(R.drawable.ic_agregar);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                click = !click;
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                    Interpolator interpolador = AnimationUtils.loadInterpolator(getBaseContext(),
                            android.R.interpolator.fast_out_slow_in);

                    view.animate()
                            .rotation(click ? 45f : 0)
                            .setInterpolator(interpolador)
                            .start();
                }
            }
        });
    }

}

Transformar Floating Action Button En Toolbar

Los principios de comportamiento del fab en Material Design, sugieren que es posible transformar este componente en otros elementos que extiendan su funcionalidad. Ya sean toolbars, menús, hojas de material, diálogos, etc.

Llevar a cabo este tipo de animaciones es complejo debido a la orquestación que se debe realizar entre las animaciones de desplazamiento y forma del floating action button junto al otro componente final.

Sin embargo me encontré una librería muy interesante que te permitirá realizar un «morphing» de fab a Toolbar. Su nombre FABToolbar y a continuación te dejo un pequeño ejemplo de su uso.

Nota: Esta librería soporta versiones del SDK de Android mayores o iguales a 15.

Ejemplo…

1. Abre tu archivo build.gradle y añade la dependencia compile com.github.fafaldo:fab-toolbar:1.2.0 :

build.gradle

dependencies {
    ...

    compile 'com.github.fafaldo:fab-toolbar:1.2.0'
}

2. Esta librería usa un componente personalizado llamado FABToolbarLayout, el cual debe albergar una envoltura para el floating action button(un RelativeLayout quedaría bien) y el segundo un contenedor para los ítems de la Toolbar (un componente que extienda de ViewGroup).

El layout de la actividad quedaría así:

actividad_principal.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    android:fitsSystemWindows="true"
    tools:context="com.herprogramacion.floatingactionbutton.ActividadPrincipal">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

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


    <com.github.fafaldo.fabtoolbar.widget.FABToolbarLayout
        android:id="@+id/fabtoolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:containerId="@+id/fabtoolbar_container"
        app:fabId="@+id/fab"
        app:fabToolbarId="@+id/fabtoolbar_toolbar"
        app:fadeInFraction="0.2"
        app:hideDuration="600"
        app:horizontalMargin="@dimen/margenes_fab"
        app:showDuration="600"
        app:verticalMargin="@dimen/margenes_fab">

        <include layout="@layout/content_actividad_principal" />

        <RelativeLayout
            android:id="@id/fabtoolbar_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.design.widget.FloatingActionButton
                android:id="@id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/abc_ic_menu_share_mtrl_alpha"
                app:backgroundTint="@color/azul400"
                app:borderWidth="0dp"
                app:fabSize="normal" />

        </RelativeLayout>

        <LinearLayout
            android:id="@id/fabtoolbar_toolbar"
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:layout_alignParentBottom="true"
            android:orientation="horizontal">

            <ImageView
                android:id="@+id/uno"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:scaleType="centerInside"
                android:src="@drawable/abc_ic_menu_copy_mtrl_am_alpha" />

            <ImageView
                android:id="@+id/dos"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:scaleType="centerInside"
                android:src="@drawable/abc_ic_menu_paste_mtrl_am_alpha" />

            <ImageView
                android:id="@+id/tres"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:scaleType="centerInside"
                android:src="@drawable/abc_ic_menu_selectall_mtrl_alpha" />

            <ImageView
                android:id="@+id/cuatro"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:scaleType="centerInside"
                android:src="@drawable/abc_ic_menu_cut_mtrl_alpha" />

        </LinearLayout>

    </com.github.fafaldo.fabtoolbar.widget.FABToolbarLayout>


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

Como ves, el fab se encierra en un relative layout y los ítems que tendrá la toolbar irán en un linear layout para distribuir por igual los elementos horizontalmente.

La siguiente es una tabla de los atributos más relevantes del FABToolbarLayout:

Atributo Descripción
app:containerId Referencia al id del contenedor del fab
app:fabId Referencia al id del fab
app:fabToolbarId Referencia al id del view que representa el contenido del toolbar
app:fadeInFraction Porcentaje de desplazamiento del fab en la animación .
app:hideDuration Tiempo en milisegundos que dura la animación de toolbar a fab
app:showDuration Tiempo en milisegundos que dura la animación de fab a toolbar
app:horizontalMargin|app:verticalMargin Márgenes horizontales y verticales del fab con respecto al FABToolbarLayout

3. Para convertir el fab en toolbar usa el método show() y en caso contrario usa hide(). Para evidenciar este comportamiento abre tu actividad principal y consigue la instancia del FABToolbarLayout, el FAB y los cuatro ítems de selección.

Luego implementa en la actividad la escucha View.OnClickListener(). Asigna dicha interfaz a los  views y procesa el comportamiento en onClick() estableciendo la ejecución de hide() para los ítems de la toolbar.

En caso de que sea el fab usa el método show().

ActividadPrincipal.java

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;

import com.github.fafaldo.fabtoolbar.widget.FABToolbarLayout;

public class ActividadPrincipal extends AppCompatActivity implements View.OnClickListener {

    private FABToolbarLayout morph;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.actividad_principal);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        morph = (FABToolbarLayout) findViewById(R.id.fabtoolbar);

        View uno, dos, tres, cuatro;

        uno = findViewById(R.id.uno);
        dos = findViewById(R.id.dos);
        cuatro = findViewById(R.id.cuatro);
        tres = findViewById(R.id.tres);

        fab.setOnClickListener(this);
        uno.setOnClickListener(this);
        dos.setOnClickListener(this);
        tres.setOnClickListener(this);
        cuatro.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.fab) {
            morph.show();
        }

        morph.hide();
    }
}

Floating Action Button con menú

Otro posible comportamiento del fab es la visualización de un menú de mini fabs que promuevan acciones derivadas de la principal. A esto también se le llama «Speed dial».

Para crear esta extensión usaré la librería FloatingActionButton de futuressimple, la cual permite crear un menú desde un fab de forma sencilla.

Veamos cómo hacerlo:

1.  Agrega al archivo build.gradle la dependencia compile com.getbase:floatingactionbutton:1.10.1 de la siguiente forma:

dependencies {
    ...

    compile 'com.getbase:floatingactionbutton:1.10.1'

}

2. Para crear el menú debes usar el componente personalizado FloatingActionsMenu, el cual lleva en su interior todos los fabs que serán opciones para el despliegue. El primer hijo aparecerá en la parte superior y le seguirán los demás en orden descendente.

Algunos de los atributos más relevantes para el menú son:

Atributo Descripción
fab:fab_addButtonSize Determina el tamaño del fab de origen del menú. Al igual que la clase original, puedes usar mini y normal.
fab:fab_addButtonColorNormal Determina el color del background del fab para menú
fab:fab_labelStyle Estilo de fondo para las etiquetas que se proyectan en cada opción del menú. Puedes crear una propia en tu archivo values/styles.xml o utilizar la que viene por defecto.
fab:fab_labelsPosition Posición relativa de las etiquetas. Usa left y right para determinar a la izquierda o derecha.

En los fab subordinados los más elementales son:

Atributo Descripción
fab:fab_colorNormal Color del floating action button
fab:fab_icon Icono para el fab
fab:fab_size Cambia el tamaño del fab
fab:fab_title Texto que saldrá en la etiqueta del fab

Teniendo esto en cuenta crearemos el siguiente diseño:

Tendremos un menú con tres mini fabs, donde el primero tendrá el color primario y los subordinados el color del acento.

actividad_principal.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:fab="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.herprogramacion.floatingactionbutton.ActividadPrincipal">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

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

    <include layout="@layout/content_actividad_principal" />

    <com.getbase.floatingactionbutton.FloatingActionsMenu
        android:id="@+id/menu_fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/margenes_fab"
        app:fab_labelStyle="@style/Etiquetas"
        fab:fab_addButtonColorNormal="?attr/colorPrimary"
        fab:fab_addButtonSize="normal"
        fab:fab_labelStyle="@style/Etiquetas"
        fab:fab_labelsPosition="left">

        <com.getbase.floatingactionbutton.FloatingActionButton
            android:id="@+id/accion_favorito"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_colorNormal="?attr/colorAccent"
            fab:fab_icon="@drawable/ic_favorito"
            fab:fab_size="mini"
            fab:fab_title="Favorito" />

        <com.getbase.floatingactionbutton.FloatingActionButton
            android:id="@+id/accion_buscar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_colorNormal="?attr/colorAccent"
            fab:fab_icon="@drawable/ic_buscar"
            fab:fab_size="mini"
            fab:fab_title="Buscar" />

        <com.getbase.floatingactionbutton.FloatingActionButton
            android:id="@+id/accion_carrito"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            fab:fab_colorNormal="?attr/colorAccent"
            fab:fab_icon="@drawable/ic_carro_compra"
            fab:fab_size="mini"
            fab:fab_title="Añadir a la cesta" />

    </com.getbase.floatingactionbutton.FloatingActionsMenu>

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

Como ves las etiquetas se encuentran a la izquierda y cada elemento tiene su propio icono personalizado.

3. El estilo de las etiquetas se basa en un fondo oscuro semitransparente con un texto de color blanco.

Dentro de styles.xml

<style name="Etiquetas">
    <item name="android:background">@drawable/background_label_fab</item>
    <item name="android:textColor">@color/white</item>
</style>

El background es un rectángulo con bordes curvos muy sencillo. Crea una nuevo archivo xml dentro de drawable, llámalo background_label_fab.xml y agrega la siguiente definición:

background_label_fab.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/negro_semitransparente"/>
    <padding
        android:left="16dp"
        android:top="4dp"
        android:right="16dp"
        android:bottom="4dp"/>
    <corners
        android:radius="2dp"/>
</shape>

Los colores usados puedes definirlos en tu archivo colors.xml de la siguiente forma:

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#00796B</color>
    <color name="colorPrimaryDark">#26A69A</color>
    <color name="colorAccent">#ef5350</color>

    <color name="negro_semitransparente">#B2000000</color>
    <color name="blanco">#fafafa</color>
</resources>

El comportamiento para cada acción puedes generarla con una escucha View.OnClickListener como vimos al inicio. Para que el menú funcione no es necesario realizar la llamada de algún método.

Conclusión

El Floating Action Button es un componente estilizado y consistente para simplificar el acceso a una tarea principal. Su versatilidad permite crear nuevas acciones y verificaciones al cambiar de forma o posición.

Su uso no algo fuera de lo normal, ya que actúa como un botón corriente, sin embargo si deseas transformar su comportamiento es necesario que aprendas a crear animaciones, generar morphings y atar su comportamiento a otros elementos como la Toolbar, Menús contextuales, paneles simples, etc.

Salir de la versión móvil