1page.title=Como definir animações personalizadas 2 3@jd:body 4 5<div id="tb-wrapper"> 6<div id="tb"> 7<h2>Esta lição ensina a</h2> 8<ol> 9 <li><a href="#Touch">Personalizar feedback de toque</a></li> 10 <li><a href="#Reveal">Usar o efeito de revelação</a></li> 11 <li><a href="#Transitions">Personalizar transições de atividades</a></li> 12 <li><a href="#ViewState">Animar mudança de estado da visualização</a></li> 13 <li><a href="#AnimVector">Animar desenháveis de vetor</a></li> 14</ol> 15<h2>Você também deve ler</h2> 16<ul> 17 <li><a href="http://www.google.com/design/spec">Especificações do Material Design</a></li> 18 <li><a href="{@docRoot}design/material/index.html">Material Design no Android</a></li> 19</ul> 20</div> 21</div> 22 23 24<p>As animações no Material Design dão feedback aos usuários sobre as ações deles e fornecem 25continuidade visual à medida que interagem com o seu aplicativo. O tema do Material fornece algumas animações padrão para 26botões e transições de atividades e o Android 5.0 (API de nível 21) e posteriores permitem a personalização 27dessas animações e a criação de novas:</p> 28 29<ul> 30<li>Feedback de toque</li> 31<li>Revelação circular</li> 32<li>Transições de atividades</li> 33<li>Movimento curvado</li> 34<li>Mudanças de estado da visualização</li> 35</ul> 36 37 38<h2 id="Touch">Personalizar feedback de toque</h2> 39 40<p>Os feedbacks de toque no Material Design fornecem confirmação visual instantânea no 41ponto de contato quando os usuários interagem com elementos da interface do usuário. As animações de feedback de toque padrão 42para botões usam a nova classe {@link android.graphics.drawable.RippleDrawable}, que passa por transições 43entre diferentes estados com um efeito de ondulação.</p> 44 45<p>Na maioria dos casos, você deve aplicar essa funcionalidade no XML de visualização especificando o segundo plano da 46visualização como:</p> 47 48<ul> 49<li><code>?android:attr/selectableItemBackground</code> para uma ondulação delimitada.</li> 50<li><code>?android:attr/selectableItemBackgroundBorderless</code> para uma ondulação que se estenda além 51da visualização. Ele será desenhado sobre e delimitado pelo pai mais próximo da visualização com um segundo plano 52não nulo.</li> 53</ul> 54 55<p class="note"><strong>Observação:</strong> <code>selectableItemBackgroundBorderless</code> é um novo 56atributo introduzido na API de nível 21.</p> 57 58 59<p>Alternativamente, você pode definir um {@link android.graphics.drawable.RippleDrawable} 60como um recurso XML usando o elemento <code>ripple</code>.</p> 61 62<p>Você pode atribuir uma cor para objetos {@link android.graphics.drawable.RippleDrawable}. Para alterar 63a cor do feedback de toque padrão, use o atributo <code>android:colorControlHighlight</code> 64do tema.</p> 65 66<p>Para obter mais informações, consulte a referência de API para a classe {@link 67android.graphics.drawable.RippleDrawable}.</p> 68 69 70<h2 id="Reveal">Usar o efeito de revelação</h2> 71 72<p>Revelar animações fornece continuidade visual aos usuários ao exibir ou esconder um grupo 73de elementos da interface do usuário. O método {@link android.view.ViewAnimationUtils#createCircularReveal 74ViewAnimationUtils.createCircularReveal()} permite animar um círculo de recorte para 75revelar ou ocultar uma visualização.</p> 76 77<p>Para revelar uma visualização anteriormente invisível usando esse efeito:</p> 78 79<pre> 80// previously invisible view 81View myView = findViewById(R.id.my_view); 82 83// get the center for the clipping circle 84int cx = (myView.getLeft() + myView.getRight()) / 2; 85int cy = (myView.getTop() + myView.getBottom()) / 2; 86 87// get the final radius for the clipping circle 88int finalRadius = Math.max(myView.getWidth(), myView.getHeight()); 89 90// create the animator for this view (the start radius is zero) 91Animator anim = 92 ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius); 93 94// make the view visible and start the animation 95myView.setVisibility(View.VISIBLE); 96anim.start(); 97</pre> 98 99<p>Para esconder uma visualização anteriormente visível usando esse efeito:</p> 100 101<pre> 102// previously visible view 103final View myView = findViewById(R.id.my_view); 104 105// get the center for the clipping circle 106int cx = (myView.getLeft() + myView.getRight()) / 2; 107int cy = (myView.getTop() + myView.getBottom()) / 2; 108 109// get the initial radius for the clipping circle 110int initialRadius = myView.getWidth(); 111 112// create the animation (the final radius is zero) 113Animator anim = 114 ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); 115 116// make the view invisible when the animation is done 117anim.addListener(new AnimatorListenerAdapter() { 118 @Override 119 public void onAnimationEnd(Animator animation) { 120 super.onAnimationEnd(animation); 121 myView.setVisibility(View.INVISIBLE); 122 } 123}); 124 125// start the animation 126anim.start(); 127</pre> 128 129 130<h2 id="Transitions">Personalizar transições de atividades</h2> 131 132<!-- shared transition video --> 133<div style="width:290px;margin-left:35px;float:right"> 134 <div class="framed-nexus5-port-span-5"> 135 <video class="play-on-hover" autoplay=""> 136 <source src="{@docRoot}design/material/videos/ContactsAnim.mp4"> 137 <source src="{@docRoot}design/material/videos/ContactsAnim.webm"> 138 <source src="{@docRoot}design/material/videos/ContactsAnim.ogv"> 139 </video> 140 </div> 141 <div style="font-size:10pt;margin-left:20px;margin-bottom:30px"> 142 <p class="img-caption" style="margin-top:3px;margin-bottom:10px"><strong>Figura 1</strong> - uma 143 transição com elementos compartilhados.</p> 144 <em>Para reproduzir o filme, clique na tela do dispositivo</em> 145 </div> 146</div> 147 148<p>As transições de atividades em aplicativos com Material Design fornecem conexões visuais 149entre estados diferentes por meio de movimentos e transformações entre elementos comuns. Você pode especificar animações personalizadas para 150transições de entrada e de saída e para transições de elementos compartilhados entre atividades.</p> 151 152<ul> 153<li>Uma transição de <strong>entrada</strong> determina como as visualizações em uma atividade entram em cena. 154Por exemplo, na transição de entrada <em>explodir</em>, as visualizações entram em cena por fora 155e voam em direção ao centro da tela.</li> 156 157<li>Uma transição de <strong>saída</strong> determina como as visualizações em uma atividade saem de cena. Por 158 exemplo, na transição de saída <em>explodir</em>, as visualizações saem de cena a partir do 159centro.</li> 160 161<li>Uma transição de <strong>elementos compartilhados</strong> determina como as visualizações compartilhadas 162entre duas atividades fazem transição entre essas atividades. Por exemplo, se duas atividades têm a mesma 163imagem em posições e tamanhos diferentes, a transição de elemento compartilhado <em>changeImageTransform</em> converte 164e dimensiona a imagem suavemente entre essas atividades.</li> 165</ul> 166 167<p>O Android 5.0 (API de nível 21) é compatível com estas transições de entrada e de saída:</p> 168 169<ul> 170<li><em>explodir</em> - move as visualizações para dentro ou para fora partindo do centro da cena.</li> 171<li><em>deslizar</em> - move as visualizações para dentro ou para fora partindo de um dos cantos da cena.</li> 172<li><em>esmaecer</em> - adiciona ou remove uma visualização de uma cena alterando a opacidade.</li> 173</ul> 174 175<p>Qualquer transição que amplie a classe {@link android.transition.Visibility} é suportada 176como uma transição de entrada ou de saída. Para obter mais informações, consulte a referência de API para a classe 177{@link android.transition.Transition}.</p> 178 179<p>O Android 5.0 (API de nível 21) também é compatível com estas transições de elementos compartilhados:</p> 180 181<ul> 182<li><em>changeBounds</em> - anima as mudanças das visualizações desejadas em limites do layout.</li> 183<li><em>changeBounds</em> - anima as mudanças das visualizações desejadas em limites de corte.</li> 184<li><em>changeBounds</em> - anima as mudanças das visualizações desejadas em escala e rotação.</li> 185<li><em>changeImageTransform</em> - anima as mudanças das imagens desejadas em tamanho e escala.</li> 186</ul> 187 188<p>Ao habilitar as transições de atividades no seu aplicativo, a transição de esmaecimento cruzado padrão é 189ativada entre as atividades de entrada e saída.</p> 190 191<img src="{@docRoot}training/material/images/SceneTransition.png" alt="" width="600" height="405" style="margin-top:20px" /> 192<p class="img-caption"> 193 <strong>Figura 2</strong> - uma transição de cena com um elemento compartilhado. 194</p> 195 196<h3>Especificar transições de atividades</h3> 197 198<p>Primeiro, habilite as transições de conteúdo da janela com o atributo <code>android:windowContentTransitions</code> 199ao definir um estilo herdado do tema do Material. Você também pode especificar 200transições de entrada, saída e elemento compartilhado na definição de estilo:</p> 201 202<pre> 203<style name="BaseAppTheme" parent="android:Theme.Material"> 204 <!-- enable window content transitions --> 205 <item name="android:windowContentTransitions">true</item> 206 207 <!-- specify enter and exit transitions --> 208 <item name="android:windowEnterTransition">@transition/explode</item> 209 <item name="android:windowExitTransition">@transition/explode</item> 210 211 <!-- specify shared element transitions --> 212 <item name="android:windowSharedElementEnterTransition"> 213 @transition/change_image_transform</item> 214 <item name="android:windowSharedElementExitTransition"> 215 @transition/change_image_transform</item> 216</style> 217</pre> 218 219<p>A transição <code>change_image_transform</code> nesse exemplo é definida a seguir:</p> 220 221<pre> 222<!-- res/transition/change_image_transform.xml --> 223<!-- (see also Shared Transitions below) --> 224<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> 225 <changeImageTransform/> 226</transitionSet> 227</pre> 228 229<p>O elemento <code>changeImageTransform</code> corresponde à classe 230{@link android.transition.ChangeImageTransform}. Para obter mais informações, consulte a referência de 231API para {@link android.transition.Transition}.</p> 232 233<p>Para habilitar transições de conteúdo da janela no código como alternativa, chame o método 234{@link android.view.Window#requestFeature Window.requestFeature()}:</p> 235 236<pre> 237// inside your activity (if you did not enable transitions in your theme) 238getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); 239 240// set an exit transition 241getWindow().setExitTransition(new Explode()); 242</pre> 243 244<p>Para especificar transições no código, chame os métodos a seguir com um objeto {@link 245android.transition.Transition}:</p> 246 247<ul> 248 <li>{@link android.view.Window#setEnterTransition Window.setEnterTransition()}</li> 249 <li>{@link android.view.Window#setExitTransition Window.setExitTransition()}</li> 250 <li>{@link android.view.Window#setSharedElementEnterTransition 251 Window.setSharedElementEnterTransition()}</li> 252 <li>{@link android.view.Window#setSharedElementExitTransition 253 Window.setSharedElementExitTransition()}</li> 254</ul> 255 256<p>Os métodos {@link android.view.Window#setExitTransition setExitTransition()} e {@link 257android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} definem 258a transição de saída para a atividade de chamada. Os métodos {@link android.view.Window#setEnterTransition 259setEnterTransition()} e {@link android.view.Window#setSharedElementEnterTransition 260setSharedElementEnterTransition()} definem a transição de entrada para a atividade chamada.</p> 261 262<p>Para obter o efeito completo de uma transição, você deve habilitar as transições de conteúdo da janela tanto na atividade 263chamada quanto na atividade de chamada. Caso contrário, a atividade de chamada acionará a transição de saída, 264mas você verá uma transição de janela (como dimensionamento ou esmaecimento).</p> 265 266<p>Para iniciar uma transição de entrada o mais cedo possível, use o método 267{@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()} 268na atividade chamada. Isso faz com que haja transições de entrada mais dramáticas.</p> 269 270<h3>Iniciar uma atividade usando transições</h3> 271 272<p>Se você habilita as transições e define uma transição de saída para uma atividade, a transição 273será ativada ao iniciar outra atividade, como a seguir:</p> 274 275<pre> 276startActivity(intent, 277 ActivityOptions.makeSceneTransitionAnimation(this).toBundle()); 278</pre> 279 280<p>Se você configurou uma transição de entrada para a segunda atividade, a transição também 281será ativada quando a atividade for iniciada. Para desabilitar as transições ao iniciar outra atividade, forneça um pacote de 282opções <code>null</code>.</p> 283 284<h3>Iniciar uma atividade com um elemento compartilhado</h3> 285 286<p>Para criar uma animação de transição de tela entre duas atividades que têm um elemento compartilhado:</p> 287 288<ol> 289<li>Habilite transições de conteúdo da janela no tema.</li> 290<li>Especifique uma transição de elementos compartilhados no estilo.</li> 291<li>Defina a transição como um recurso XML.</li> 292<li>Atribua um nome comum aos elementos compartilhados em ambos os layouts com o atributo 293 <code>android:transitionName</code>.</li> 294<li>Use o método {@link android.app.ActivityOptions#makeSceneTransitionAnimation 295ActivityOptions.makeSceneTransitionAnimation()}.</li> 296</ol> 297 298<pre> 299// get the element that receives the click event 300final View imgContainerView = findViewById(R.id.img_container); 301 302// get the common element for the transition in this activity 303final View androidRobotView = findViewById(R.id.image_small); 304 305// define a click listener 306imgContainerView.setOnClickListener(new View.OnClickListener() { 307 @Override 308 public void onClick(View view) { 309 Intent intent = new Intent(this, Activity2.class); 310 // create the transition animation - the images in the layouts 311 // of both activities are defined with android:transitionName="robot" 312 ActivityOptions options = ActivityOptions 313 .makeSceneTransitionAnimation(this, androidRobotView, "robot"); 314 // start the new activity 315 startActivity(intent, options.toBundle()); 316 } 317}); 318</pre> 319 320<p>Para obter visualizações dinâmicas compartilhadas geradas no código, use o método 321{@link android.view.View#setTransitionName View.setTransitionName()} para especificar um nome de 322elemento comum em ambas as atividades.</p> 323 324<p>Para reverter a animação de transição de cena ao finalizar a segunda atividade, chame o método 325{@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()} 326em vez de {@link android.app.Activity#finish Activity.finish()}.</p> 327 328<h3>Iniciar uma atividade com diversos elementos compartilhados</h3> 329 330<p>Para criar uma animação de transição de cena entre duas atividades que têm mais de um elemento 331compartilhado, defina os elementos compartilhados em ambos os layouts com o atributo <code>android:transitionName</code> 332(ou use o método {@link android.view.View#setTransitionName View.setTransitionName()} em ambas 333as atividades) e crie um objeto {@link android.app.ActivityOptions}, como a seguir:</p> 334 335<pre> 336ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, 337 Pair.create(view1, "agreedName1"), 338 Pair.create(view2, "agreedName2")); 339</pre> 340 341 342<h2 id="CurvedMotion">Usar movimento curvado</h2> 343 344<p>As animações no Material Design dependem das curvas para obter padrões de interpolação 345de 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 346temporização personalizada e de movimentos curvados para animações.</p> 347 348<p>A classe {@link android.view.animation.PathInterpolator} é um novo interpolador baseado em uma 349curva Bézier ou em um objeto {@link android.graphics.Path}. Esse interpolador especifica uma curva de movimento em 350um quadrado de 1x1, com pontos de ancoragem em (0,0) e (1,1) e pontos de controle conforme especificado usando 351os argumentos do construtor. Você também pode definir um interpolador de caminho como um recurso XML:</p> 352 353<pre> 354<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" 355 android:controlX1="0.4" 356 android:controlY1="0" 357 android:controlX2="1" 358 android:controlY2="1"/> 359</pre> 360 361<p>O sistema fornece recursos XML para três curvas básicas na especificação do 362Material Design:</p> 363 364<ul> 365 <li><code>@interpolator/fast_out_linear_in.xml</code></li> 366 <li><code>@interpolator/fast_out_slow_in.xml</code></li> 367 <li><code>@interpolator/linear_out_slow_in.xml</code></li> 368</ul> 369 370<p>Você pode passar um objeto {@link android.view.animation.PathInterpolator} para o método {@link 371android.animation.Animator#setInterpolator Animator.setInterpolator()}.</p> 372 373<p>A classe {@link android.animation.ObjectAnimator} tem novos construtores que permitem a animação de 374coordenadas ao longo de um caminho usando duas ou mais propriedades simultaneamente. Por exemplo, o animador a seguir usa um 375objeto {@link android.graphics.Path} para animar as propriedades X e Y de uma visualização:</p> 376 377<pre> 378ObjectAnimator mAnimator; 379mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); 380... 381mAnimator.start(); 382</pre> 383 384 385<h2 id="ViewState">Animar mudança de estado da visualização</h2> 386 387<p>A classe {@link android.animation.StateListAnimator} permite a definição de animadores que são executados 388quando o estado de uma visualização muda. O exemplo a seguir mostra como definir um {@link 389android.animation.StateListAnimator} como um recurso XML:</p> 390 391<pre> 392<!-- animate the translationZ property of a view when pressed --> 393<selector xmlns:android="http://schemas.android.com/apk/res/android"> 394 <item android:state_pressed="true"> 395 <set> 396 <objectAnimator android:propertyName="translationZ" 397 android:duration="@android:integer/config_shortAnimTime" 398 android:valueTo="2dp" 399 android:valueType="floatType"/> 400 <!-- you could have other objectAnimator elements 401 here for "x" and "y", or other properties --> 402 </set> 403 </item> 404 <item android:state_enabled="true" 405 android:state_pressed="false" 406 android:state_focused="true"> 407 <set> 408 <objectAnimator android:propertyName="translationZ" 409 android:duration="100" 410 android:valueTo="0" 411 android:valueType="floatType"/> 412 </set> 413 </item> 414</selector> 415</pre> 416 417<p>Para anexar animações de estado de visualização personalizadas a uma visualização, defina um animador usando o elemento 418<code>selector</code> em um arquivo de recurso XML, como nesse exemplo, e 419atribua-o à visualização com o atributo <code>android:stateListAnimator</code>. Para atribuir um animador de lista de estado 420a uma visualização no código, use o método {@link android.animation.AnimatorInflater#loadStateListAnimator 421AnimationInflater.loadStateListAnimator()} e atribua o animador à visualização com o método 422{@link android.view.View#setStateListAnimator View.setStateListAnimator()}.</p> 423 424<p>Quando o tema amplia o tema do Material, os botões têm uma animação Z por padrão. Para evitar esse 425comportamento nos botões, defina o atributo <code>android:stateListAnimator</code> como 426<code>@null</code>.</p> 427 428<p>A classe {@link android.graphics.drawable.AnimatedStateListDrawable} permite a criação de 429desenháveis que exibem animações entre mudanças de estado da visualização associada. Alguns dos widgets de sistema no 430Android 5.0 usam essas animações por padrão. O exemplo a seguir mostra como 431definir um {@link android.graphics.drawable.AnimatedStateListDrawable} como um recurso XML:</p> 432 433<pre> 434<!-- res/drawable/myanimstatedrawable.xml --> 435<animated-selector 436 xmlns:android="http://schemas.android.com/apk/res/android"> 437 438 <!-- provide a different drawable for each state--> 439 <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" 440 android:state_pressed="true"/> 441 <item android:id="@+id/focused" android:drawable="@drawable/drawableF" 442 android:state_focused="true"/> 443 <item android:id="@id/default" 444 android:drawable="@drawable/drawableD"/> 445 446 <!-- specify a transition --> 447 <transition android:fromId="@+id/default" android:toId="@+id/pressed"> 448 <animation-list> 449 <item android:duration="15" android:drawable="@drawable/dt1"/> 450 <item android:duration="15" android:drawable="@drawable/dt2"/> 451 ... 452 </animation-list> 453 </transition> 454 ... 455</animated-selector> 456</pre> 457 458 459<h2 id="AnimVector">Animar desenháveis de vetor</h2> 460 461<p><a href="{@docRoot}training/material/drawables.html#VectorDrawables">Desenháveis de vetor</a> são 462dimensionáveis sem perder definição. A classe {@link android.graphics.drawable.AnimatedVectorDrawable} 463permite a animação de propriedades de um desenhável de vetor.</p> 464 465<p>Você normalmente define desenháveis de vetor animados em três arquivos XML:</p> 466 467<ul> 468<li>Um desenhável de vetor com o elemento <code><vector></code> em 469<code>res/drawable/</code></li> 470<li>Um desenhável de vetor animado com o elemento <code><animated-vector></code> em 471<code>res/drawable/</code></li> 472<li>Um ou mais animadores de objeto com o elemento <code><objectAnimator></code> em 473<code>res/anim/</code></li> 474</ul> 475 476<p>Desenháveis de vetor animados podem animar os atributos dos elementos <code><group></code> e 477<code><path></code>. Os elementos <code><group></code> definem um conjunto de 478caminhos ou subgrupos e o elemento <code><path></code> define caminhos a serem desenhados.</p> 479 480<p>Ao definir um desenhável de vetor que você queira animar, use o atributo <code>android:name</code> 481para atribuir um nome único a grupos e caminhos para poder referenciá-los nas definições 482do animador. Por exemplo:</p> 483 484<pre> 485<!-- res/drawable/vectordrawable.xml --> 486<vector xmlns:android="http://schemas.android.com/apk/res/android" 487 android:height="64dp" 488 android:width="64dp" 489 android:viewportHeight="600" 490 android:viewportWidth="600"> 491 <group 492 <strong>android:name="rotationGroup"</strong> 493 android:pivotX="300.0" 494 android:pivotY="300.0" 495 android:rotation="45.0" > 496 <path 497 <strong>android:name="v"</strong> 498 android:fillColor="#000000" 499 android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> 500 </group> 501</vector> 502</pre> 503 504<p>A definição de desenhável de vetor animado se refere a grupos e caminhos no desenhável de vetor 505pelos respectivos nomes:</p> 506 507<pre> 508<!-- res/drawable/animvectordrawable.xml --> 509<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" 510 android:drawable="@drawable/vectordrawable" > 511 <target 512 android:name="rotationGroup" 513 android:animation="@anim/rotation" /> 514 <target 515 android:name="v" 516 android:animation="@anim/path_morph" /> 517</animated-vector> 518</pre> 519 520<p>As definições de animação representam objetos {@link android.animation.ObjectAnimator} ou {@link 521android.animation.AnimatorSet}. O primeiro animador nesse exemplo gira o grupo 522desejado em 360º:</p> 523 524<pre> 525<!-- res/anim/rotation.xml --> 526<objectAnimator 527 android:duration="6000" 528 android:propertyName="rotation" 529 android:valueFrom="0" 530 android:valueTo="360" /> 531</pre> 532 533<p>O segundo animador nesse exemplo transforma a forma do caminho do desenhável 534de vetor. Ambos os caminhos devem ser compatíveis com a transformação: eles precisam ter o mesmo 535número de comandos e de parâmetros para cada comando.</p> 536 537<pre> 538<!-- res/anim/path_morph.xml --> 539<set xmlns:android="http://schemas.android.com/apk/res/android"> 540 <objectAnimator 541 android:duration="3000" 542 android:propertyName="pathData" 543 android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" 544 android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" 545 android:valueType="pathType" /> 546</set> 547</pre> 548 549<p>Para obter mais informações, consulte a referência de API para {@link 550android.graphics.drawable.AnimatedVectorDrawable}.</p> 551