page.title=Como definir animações personalizadas

@jd:body

<div id="tb-wrapper">
<div id="tb">
<h2>Esta lição ensina a</h2>
<ol>
  <li><a href="#Touch">Personalizar feedback de toque</a></li>
  <li><a href="#Reveal">Usar o efeito de revelação</a></li>
  <li><a href="#Transitions">Personalizar transições de atividades</a></li>
  <li><a href="#ViewState">Animar mudança de estado da visualização</a></li>
  <li><a href="#AnimVector">Animar desenháveis de vetor</a></li>
</ol>
<h2>Você também deve ler</h2>
<ul>
  <li><a href="http://www.google.com/design/spec">Especificações do Material Design</a></li>
  <li><a href="{@docRoot}design/material/index.html">Material Design no Android</a></li>
</ul>
</div>
</div>


<p>As animações no Material Design dão feedback aos usuários sobre as ações deles e fornecem
continuidade visual à medida que interagem com o seu aplicativo. O tema do Material fornece algumas animações padrão para
botões e transições de atividades e o Android 5.0 (API de nível 21) e posteriores permitem a personalização
dessas animações e a criação de novas:</p>

<ul>
<li>Feedback de toque</li>
<li>Revelação circular</li>
<li>Transições de atividades</li>
<li>Movimento curvado</li>
<li>Mudanças de estado da visualização</li>
</ul>


<h2 id="Touch">Personalizar feedback de toque</h2>

<p>Os feedbacks de toque no Material Design fornecem confirmação visual instantânea no
ponto de contato quando os usuários interagem com elementos da interface do usuário. As animações de feedback de toque padrão
para botões usam a nova classe {@link android.graphics.drawable.RippleDrawable}, que passa por transições
entre diferentes estados com um efeito de ondulação.</p>

<p>Na maioria dos casos, você deve aplicar essa funcionalidade no XML de visualização especificando o segundo plano da
visualização como:</p>

<ul>
<li><code>?android:attr/selectableItemBackground</code> para uma ondulação delimitada.</li>
<li><code>?android:attr/selectableItemBackgroundBorderless</code> para uma ondulação que se estenda além
da visualização. Ele será desenhado sobre e delimitado pelo pai mais próximo da visualização com um segundo plano
não nulo.</li>
</ul>

<p class="note"><strong>Observação:</strong> <code>selectableItemBackgroundBorderless</code> é um novo
atributo introduzido na API de nível 21.</p>


<p>Alternativamente, você pode definir um {@link android.graphics.drawable.RippleDrawable}
como um recurso XML usando o elemento <code>ripple</code>.</p>

<p>Você pode atribuir uma cor para objetos {@link android.graphics.drawable.RippleDrawable}. Para alterar
a cor do feedback de toque padrão, use o atributo <code>android:colorControlHighlight</code>
do tema.</p>

<p>Para obter mais informações, consulte a referência de API para a classe {@link
android.graphics.drawable.RippleDrawable}.</p>


<h2 id="Reveal">Usar o efeito de revelação</h2>

<p>Revelar animações fornece continuidade visual aos usuários ao exibir ou esconder um grupo
de elementos da interface do usuário. O método {@link android.view.ViewAnimationUtils#createCircularReveal
ViewAnimationUtils.createCircularReveal()} permite animar um círculo de recorte para
revelar ou ocultar uma visualização.</p>

<p>Para revelar uma visualização anteriormente invisível usando esse efeito:</p>

<pre>
// previously invisible view
View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// get the final radius for the clipping circle
int finalRadius = Math.max(myView.getWidth(), myView.getHeight());

// create the animator for this view (the start radius is zero)
Animator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);

// make the view visible and start the animation
myView.setVisibility(View.VISIBLE);
anim.start();
</pre>

<p>Para esconder uma visualização anteriormente visível usando esse efeito:</p>

<pre>
// previously visible view
final View myView = findViewById(R.id.my_view);

// get the center for the clipping circle
int cx = (myView.getLeft() + myView.getRight()) / 2;
int cy = (myView.getTop() + myView.getBottom()) / 2;

// get the initial radius for the clipping circle
int initialRadius = myView.getWidth();

// create the animation (the final radius is zero)
Animator anim =
    ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);

// make the view invisible when the animation is done
anim.addListener(new AnimatorListenerAdapter() {
    &#64;Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        myView.setVisibility(View.INVISIBLE);
    }
});

// start the animation
anim.start();
</pre>


<h2 id="Transitions">Personalizar transições de atividades</h2>

<!-- shared transition video -->
<div style="width:290px;margin-left:35px;float:right">
  <div class="framed-nexus5-port-span-5">
  <video class="play-on-hover" autoplay="">
    <source src="{@docRoot}design/material/videos/ContactsAnim.mp4">
    <source src="{@docRoot}design/material/videos/ContactsAnim.webm">
    <source src="{@docRoot}design/material/videos/ContactsAnim.ogv">
  </video>
  </div>
  <div style="font-size:10pt;margin-left:20px;margin-bottom:30px">
    <p class="img-caption" style="margin-top:3px;margin-bottom:10px"><strong>Figura 1</strong> - uma
    transição com elementos compartilhados.</p>
    <em>Para reproduzir o filme, clique na tela do dispositivo</em>
  </div>
</div>

<p>As transições de atividades em aplicativos com Material Design fornecem conexões visuais
entre estados diferentes por meio de movimentos e transformações entre elementos comuns. Você pode especificar animações personalizadas para
transições de entrada e de saída e para transições de elementos compartilhados entre atividades.</p>

<ul>
<li>Uma transição de <strong>entrada</strong> determina como as visualizações em uma atividade entram em cena.
Por exemplo, na transição de entrada <em>explodir</em>, as visualizações entram em cena por fora
e voam em direção ao centro da tela.</li>

<li>Uma transição de <strong>saída</strong> determina como as visualizações em uma atividade saem de cena. Por
  exemplo, na transição de saída <em>explodir</em>, as visualizações saem de cena a partir do
centro.</li>

<li>Uma transição de <strong>elementos compartilhados</strong> determina como as visualizações compartilhadas
entre duas atividades fazem transição entre essas atividades. Por exemplo, se duas atividades têm a mesma
imagem em posições e tamanhos diferentes, a transição de elemento compartilhado <em>changeImageTransform</em> converte
e dimensiona a imagem suavemente entre essas atividades.</li>
</ul>

<p>O Android 5.0 (API de nível 21) é compatível com estas transições de entrada e de saída:</p>

<ul>
<li><em>explodir</em> - move as visualizações para dentro ou para fora partindo do centro da cena.</li>
<li><em>deslizar</em> - move as visualizações para dentro ou para fora partindo de um dos cantos da cena.</li>
<li><em>esmaecer</em> - adiciona ou remove uma visualização de uma cena alterando a opacidade.</li>
</ul>

<p>Qualquer transição que amplie a classe {@link android.transition.Visibility} é suportada
como uma transição de entrada ou de saída. Para obter mais informações, consulte a referência de API para a classe
{@link android.transition.Transition}.</p>

<p>O Android 5.0 (API de nível 21) também é compatível com estas transições de elementos compartilhados:</p>

<ul>
<li><em>changeBounds</em> - anima as mudanças das visualizações desejadas em limites do layout.</li>
<li><em>changeBounds</em> - anima as mudanças das visualizações desejadas em limites de corte.</li>
<li><em>changeBounds</em> - anima as mudanças das visualizações desejadas em escala e rotação.</li>
<li><em>changeImageTransform</em> - anima as mudanças das imagens desejadas em tamanho e escala.</li>
</ul>

<p>Ao habilitar as transições de atividades no seu aplicativo, a transição de esmaecimento cruzado padrão é
ativada entre as atividades de entrada e saída.</p>

<img src="{@docRoot}training/material/images/SceneTransition.png" alt="" width="600" height="405" style="margin-top:20px" />
<p class="img-caption">
  <strong>Figura 2</strong> - uma transição de cena com um elemento compartilhado.
</p>

<h3>Especificar transições de atividades</h3>

<p>Primeiro, habilite as transições de conteúdo da janela com o atributo <code>android:windowContentTransitions</code>
ao definir um estilo herdado do tema do Material. Você também pode especificar
transições de entrada, saída e elemento compartilhado na definição de estilo:</p>

<pre>
&lt;style name="BaseAppTheme" parent="android:Theme.Material">
  &lt;!-- enable window content transitions -->
  &lt;item name="android:windowContentTransitions">true&lt;/item>

  &lt;!-- specify enter and exit transitions -->
  &lt;item name="android:windowEnterTransition">@transition/explode&lt;/item>
  &lt;item name="android:windowExitTransition">@transition/explode&lt;/item>

  &lt;!-- specify shared element transitions -->
  &lt;item name="android:windowSharedElementEnterTransition">
    &#64;transition/change_image_transform&lt;/item>
  &lt;item name="android:windowSharedElementExitTransition">
    &#64;transition/change_image_transform&lt;/item>
&lt;/style>
</pre>

<p>A transição <code>change_image_transform</code> nesse exemplo é definida a seguir:</p>

<pre>
&lt;!-- res/transition/change_image_transform.xml -->
&lt;!-- (see also Shared Transitions below) -->
&lt;transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  &lt;changeImageTransform/>
&lt;/transitionSet>
</pre>

<p>O elemento <code>changeImageTransform</code> corresponde à classe
{@link android.transition.ChangeImageTransform}. Para obter mais informações, consulte a referência de
API para {@link android.transition.Transition}.</p>

<p>Para habilitar transições de conteúdo da janela no código como alternativa, chame o método
{@link android.view.Window#requestFeature Window.requestFeature()}:</p>

<pre>
// inside your activity (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

// set an exit transition
getWindow().setExitTransition(new Explode());
</pre>

<p>Para especificar transições no código, chame os métodos a seguir com um objeto {@link
android.transition.Transition}:</p>

<ul>
  <li>{@link android.view.Window#setEnterTransition Window.setEnterTransition()}</li>
  <li>{@link android.view.Window#setExitTransition Window.setExitTransition()}</li>
  <li>{@link android.view.Window#setSharedElementEnterTransition
      Window.setSharedElementEnterTransition()}</li>
  <li>{@link android.view.Window#setSharedElementExitTransition
      Window.setSharedElementExitTransition()}</li>
</ul>

<p>Os métodos {@link android.view.Window#setExitTransition setExitTransition()} e {@link
android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} definem
a transição de saída para a atividade de chamada. Os métodos {@link android.view.Window#setEnterTransition
setEnterTransition()} e {@link android.view.Window#setSharedElementEnterTransition
setSharedElementEnterTransition()} definem a transição de entrada para a atividade chamada.</p>

<p>Para obter o efeito completo de uma transição, você deve habilitar as transições de conteúdo da janela tanto na atividade
chamada quanto na atividade de chamada. Caso contrário, a atividade de chamada acionará a transição de saída,
mas você verá uma transição de janela (como dimensionamento ou esmaecimento).</p>

<p>Para iniciar uma transição de entrada o mais cedo possível, use o método
{@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()}
na atividade chamada. Isso faz com que haja transições de entrada mais dramáticas.</p>

<h3>Iniciar uma atividade usando transições</h3>

<p>Se você habilita as transições e define uma transição de saída para uma atividade, a transição
será ativada ao iniciar outra atividade, como a seguir:</p>

<pre>
startActivity(intent,
              ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
</pre>

<p>Se você configurou uma transição de entrada para a segunda atividade, a transição também
será ativada quando a atividade for iniciada. Para desabilitar as transições ao iniciar outra atividade, forneça um pacote de
opções <code>null</code>.</p>

<h3>Iniciar uma atividade com um elemento compartilhado</h3>

<p>Para criar uma animação de transição de tela entre duas atividades que têm um elemento compartilhado:</p>

<ol>
<li>Habilite transições de conteúdo da janela no tema.</li>
<li>Especifique uma transição de elementos compartilhados no estilo.</li>
<li>Defina a transição como um recurso XML.</li>
<li>Atribua um nome comum aos elementos compartilhados em ambos os layouts com o atributo
    <code>android:transitionName</code>.</li>
<li>Use o método {@link android.app.ActivityOptions#makeSceneTransitionAnimation
ActivityOptions.makeSceneTransitionAnimation()}.</li>
</ol>

<pre>
// get the element that receives the click event
final View imgContainerView = findViewById(R.id.img_container);

// get the common element for the transition in this activity
final View androidRobotView = findViewById(R.id.image_small);

// define a click listener
imgContainerView.setOnClickListener(new View.OnClickListener() {
    &#64;Override
    public void onClick(View view) {
        Intent intent = new Intent(this, Activity2.class);
        // create the transition animation - the images in the layouts
        // of both activities are defined with android:transitionName="robot"
        ActivityOptions options = ActivityOptions
            .makeSceneTransitionAnimation(this, androidRobotView, "robot");
        // start the new activity
        startActivity(intent, options.toBundle());
    }
});
</pre>

<p>Para obter visualizações dinâmicas compartilhadas geradas no código, use o método
{@link android.view.View#setTransitionName View.setTransitionName()} para especificar um nome de
elemento comum em ambas as atividades.</p>

<p>Para reverter a animação de transição de cena ao finalizar a segunda atividade, chame o método
{@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()}
em vez de {@link android.app.Activity#finish Activity.finish()}.</p>

<h3>Iniciar uma atividade com diversos elementos compartilhados</h3>

<p>Para criar uma animação de transição de cena entre duas atividades que têm mais de um elemento
compartilhado, defina os elementos compartilhados em ambos os layouts com o atributo <code>android:transitionName</code>
(ou use o método {@link android.view.View#setTransitionName View.setTransitionName()} em ambas
as atividades) e crie um objeto {@link android.app.ActivityOptions}, como a seguir:</p>

<pre>
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
        Pair.create(view1, "agreedName1"),
        Pair.create(view2, "agreedName2"));
</pre>


<h2 id="CurvedMotion">Usar movimento curvado</h2>

<p>As animações no Material Design dependem das curvas para obter padrões de interpolação
de tempo e de movimentos espaciais. Com o Android 5.0 (API de nível 21) e posteriores, você pode definir padrões de curvas de
temporização personalizada e de movimentos curvados para animações.</p>

<p>A classe {@link android.view.animation.PathInterpolator} é um novo interpolador baseado em uma
curva Bézier ou em um objeto {@link android.graphics.Path}. Esse interpolador especifica uma curva de movimento em
um quadrado de 1x1, com pontos de ancoragem em (0,0) e (1,1) e pontos de controle conforme especificado usando
os argumentos do construtor. Você também pode definir um interpolador de caminho como um recurso XML:</p>

<pre>
&lt;pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.4"
    android:controlY1="0"
    android:controlX2="1"
    android:controlY2="1"/>
</pre>

<p>O sistema fornece recursos XML para três curvas básicas na especificação do
Material Design:</p>

<ul>
  <li><code>&#64;interpolator/fast_out_linear_in.xml</code></li>
  <li><code>&#64;interpolator/fast_out_slow_in.xml</code></li>
  <li><code>&#64;interpolator/linear_out_slow_in.xml</code></li>
</ul>

<p>Você pode passar um objeto {@link android.view.animation.PathInterpolator} para o método {@link
android.animation.Animator#setInterpolator Animator.setInterpolator()}.</p>

<p>A classe {@link android.animation.ObjectAnimator} tem novos construtores que permitem a animação de
coordenadas ao longo de um caminho usando duas ou mais propriedades simultaneamente. Por exemplo, o animador a seguir usa um
objeto {@link android.graphics.Path} para animar as propriedades X e Y de uma visualização:</p>

<pre>
ObjectAnimator mAnimator;
mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
...
mAnimator.start();
</pre>


<h2 id="ViewState">Animar mudança de estado da visualização</h2>

<p>A classe {@link android.animation.StateListAnimator} permite a definição de animadores que são executados
quando o estado de uma visualização muda. O exemplo a seguir mostra como definir um {@link
android.animation.StateListAnimator} como um recurso XML:</p>

<pre>
&lt;!-- animate the translationZ property of a view when pressed -->
&lt;selector xmlns:android="http://schemas.android.com/apk/res/android">
  &lt;item android:state_pressed="true">
    &lt;set>
      &lt;objectAnimator android:propertyName="translationZ"
        android:duration="@android:integer/config_shortAnimTime"
        android:valueTo="2dp"
        android:valueType="floatType"/>
        &lt;!-- you could have other objectAnimator elements
             here for "x" and "y", or other properties -->
    &lt;/set>
  &lt;/item>
  &lt;item android:state_enabled="true"
    android:state_pressed="false"
    android:state_focused="true">
    &lt;set>
      &lt;objectAnimator android:propertyName="translationZ"
        android:duration="100"
        android:valueTo="0"
        android:valueType="floatType"/>
    &lt;/set>
  &lt;/item>
&lt;/selector>
</pre>

<p>Para anexar animações de estado de visualização personalizadas a uma visualização, defina um animador usando o elemento
<code>selector</code> em um arquivo de recurso XML, como nesse exemplo, e
atribua-o à visualização com o atributo <code>android:stateListAnimator</code>. Para atribuir um animador de lista de estado
a uma visualização no código, use o método {@link android.animation.AnimatorInflater#loadStateListAnimator
AnimationInflater.loadStateListAnimator()} e atribua o animador à visualização com o método
{@link android.view.View#setStateListAnimator View.setStateListAnimator()}.</p>

<p>Quando o tema amplia o tema do Material, os botões têm uma animação Z por padrão. Para evitar esse
comportamento nos botões, defina o atributo <code>android:stateListAnimator</code> como
<code>@null</code>.</p>

<p>A classe {@link android.graphics.drawable.AnimatedStateListDrawable} permite a criação de
desenháveis que exibem animações entre mudanças de estado da visualização associada. Alguns dos widgets de sistema no
Android 5.0 usam essas animações por padrão. O exemplo a seguir mostra como
definir um {@link android.graphics.drawable.AnimatedStateListDrawable} como um recurso XML:</p>

<pre>
&lt;!-- res/drawable/myanimstatedrawable.xml -->
&lt;animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    &lt;!-- provide a different drawable for each state-->
    &lt;item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    &lt;item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    &lt;item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>

    &lt;!-- specify a transition -->
    &lt;transition android:fromId="@+id/default" android:toId="@+id/pressed">
        &lt;animation-list>
            &lt;item android:duration="15" android:drawable="@drawable/dt1"/>
            &lt;item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        &lt;/animation-list>
    &lt;/transition>
    ...
&lt;/animated-selector>
</pre>


<h2 id="AnimVector">Animar desenháveis de vetor</h2>

<p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">Desenháveis de vetor</a> são
dimensionáveis sem perder definição. A classe {@link android.graphics.drawable.AnimatedVectorDrawable}
permite a animação de propriedades de um desenhável de vetor.</p>

<p>Você normalmente define desenháveis de vetor animados em três arquivos XML:</p>

<ul>
<li>Um desenhável de vetor com o elemento <code>&lt;vector&gt;</code> em
<code>res/drawable/</code></li>
<li>Um desenhável de vetor animado com o elemento <code>&lt;animated-vector&gt;</code> em
<code>res/drawable/</code></li>
<li>Um ou mais animadores de objeto com o elemento <code>&lt;objectAnimator&gt;</code> em
<code>res/anim/</code></li>
</ul>

<p>Desenháveis de vetor animados podem animar os atributos dos elementos <code>&lt;group&gt;</code> e
<code>&lt;path&gt;</code>. Os elementos <code>&lt;group&gt;</code> definem um conjunto de
caminhos ou subgrupos e o elemento <code>&lt;path&gt;</code> define caminhos a serem desenhados.</p>

<p>Ao definir um desenhável de vetor que você queira animar, use o atributo <code>android:name</code>
para atribuir um nome único a grupos e caminhos para poder referenciá-los nas definições
do animador. Por exemplo:</p>

<pre>
&lt;!-- res/drawable/vectordrawable.xml -->
&lt;vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600">
    &lt;group
        <strong>android:name="rotationGroup"</strong>
        android:pivotX="300.0"
        android:pivotY="300.0"
        android:rotation="45.0" >
        &lt;path
            <strong>android:name="v"</strong>
            android:fillColor="#000000"
            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    &lt;/group>
&lt;/vector>
</pre>

<p>A definição de desenhável de vetor animado se refere a grupos e caminhos no desenhável de vetor
pelos respectivos nomes:</p>

<pre>
&lt;!-- res/drawable/animvectordrawable.xml -->
&lt;animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/vectordrawable" >
    &lt;target
        android:name="rotationGroup"
        android:animation="@anim/rotation" />
    &lt;target
        android:name="v"
        android:animation="@anim/path_morph" />
&lt;/animated-vector>
</pre>

<p>As definições de animação representam objetos {@link android.animation.ObjectAnimator} ou {@link
android.animation.AnimatorSet}. O primeiro animador nesse exemplo gira o grupo
desejado em 360º:</p>

<pre>
&lt;!-- res/anim/rotation.xml -->
&lt;objectAnimator
    android:duration="6000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />
</pre>

<p>O segundo animador nesse exemplo transforma a forma do caminho do desenhável
de vetor. Ambos os caminhos devem ser compatíveis com a transformação: eles precisam ter o mesmo
número de comandos e de parâmetros para cada comando.</p>

<pre>
&lt;!-- res/anim/path_morph.xml -->
&lt;set xmlns:android="http://schemas.android.com/apk/res/android">
    &lt;objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
        android:valueType="pathType" />
&lt;/set>
</pre>

<p>Para obter mais informações, consulte a referência de API para {@link
android.graphics.drawable.AnimatedVectorDrawable}.</p>