Animator β€” инструмСнт для ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ Π½Π° Android

⭐⭐⭐⭐⭐В Ρ†Π΅Π½Ρ‚Ρ€Π΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ β€” Ρ‚ΠΈΠΏ классов Animator. ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π» Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π΅Π½ ΠΈ Π½ΠΎΠ²ΠΈΡ‡ΠΊΠ°ΠΌ Π² создании Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ, ΠΈ ΡƒΠΆΠ΅ ΠΎΠΏΡ‹Ρ‚Π½Ρ‹ΠΌ спСциалистам.

Animator β€” инструмСнт для ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ Π½Π° Android

Animator β€” инструмСнт для ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ Π½Π° Android

Animator β€” инструмСнт для ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ Π½Π° Android, фотография 1

Π­Ρ‚Π° ΡΡ‚Π°Ρ‚ΡŒΡ для Android-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ².

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ Animator?

Π‘Ρ‚Π°Ρ‚ΡŒΡ Π±Ρ‹Π»Π° Π²ΠΏΠ΅Ρ€Π²Ρ‹Π΅ ΠΎΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½Π° Π·Π΄Π΅ΡΡŒ.

НСмного истории. Π‘ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° запуска ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡ‹ Android сущСствовал Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ View Animation. ΠŸΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π°Π»ΡΡ ΠΎΠ½, ΠΊΠ°ΠΊ слСдуСт ΠΈΠ· названия, для Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ. Но ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ устройств Π² ΠΊΠΎΠ½Ρ†Π΅ Π½ΡƒΠ»Π΅Π²Ρ‹Ρ… Π±Ρ‹Π»Π° Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Π½ΠΈΠ·ΠΊΠΎΠΉ, Ρ‡Ρ‚ΠΎ ΠΎ красивых анимациях Π½ΠΈΠΊΡ‚ΠΎ особо Π½Π΅ Π΄ΡƒΠΌΠ°Π», поэтому Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ Π½Π΅ Π±Ρ‹Π» ΡƒΠ΄ΠΎΠ±Π½Ρ‹ΠΌ ΠΈ Π³ΠΈΠ±ΠΊΠΈΠΌ. Он ΠΈΠΌΠ΅Π» Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Ρ‚ΠΈΠΏΠ° Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ (TranslateAnimation, AlphaAnimation, ScaleAnimation, RotateAnimation), класс, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΠΈΡ… ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ (AnimationSet), Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с классами, унаслСдованными ΠΎΡ‚ View.

Π’ Android 3.0 появился ΠΊΡƒΠ΄Π° Π±ΠΎΠ»Π΅Π΅ Π³ΠΈΠ±ΠΊΠΈΠΉ Ρ„Ρ€Π΅ΠΉΠΌΠ²ΠΎΡ€ΠΊ Property Animation. Он ΡƒΠΌΠ΅Π΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ любоС доступноС свойство, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π»ΡŽΠ±Ρ‹ΠΌΠΈ классами. Π•Π³ΠΎ основным инструмСнтом являСтся Animator.

Animator β€” это Ρ‚ΠΈΠΏ классов, ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Ρ… для измСнСния Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π²Ρ‹Π±Ρ€Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. Π“Ρ€ΡƒΠ±ΠΎ говоря, это инструмСнт для управлСния ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ Π·Π°Π΄Π°Π½Π½ΠΎΠΉ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ измСняСт ΠΎΠΏΡ€Π΅Π΄Π΅Π»Ρ‘Π½Π½ΠΎΠ΅ свойство ΠΎΡ‚ Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ значСния ΠΊ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌΡƒ. Π’Π°ΠΊΠΈΠΌ ΠΏΠ»Π°Π²Π½ΠΎ ΠΌΠ΅Π½ΡΡŽΡ‰ΠΈΠΌΡΡ свойством Π² Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ.

ΠšΠ»Π°ΡΡΡ‹, унаслСдованныС ΠΎΡ‚ Animator

ValueAnimator (наслСдуСтся ΠΎΡ‚ Animator)

Π’ самом простом Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π΅ ΠΌΡ‹ Π·Π°Π΄Π°Ρ‘ΠΌ этому классу Ρ‚ΠΈΠΏ измСняСмого значСния, Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΈ запускаСм. Π’ ΠΎΡ‚Π²Π΅Ρ‚ Π½Π°ΠΌ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ события Π½Π° Π½Π°Ρ‡Π°Π»ΠΎ, ΠΊΠΎΠ½Π΅Ρ†, ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‚ΠΌΠ΅Π½Ρƒ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ ΠΈ Π΅Ρ‰Ρ‘ Π½Π° Π΄Π²Π° события, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π·Π°Π΄Π°ΡŽΡ‚ΡΡ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ для ΠΏΠ°ΡƒΠ·Ρ‹ ΠΈ измСнСния значСния. Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ измСнСния, ΠΏΠΎΠΆΠ°Π»ΡƒΠΉ, самоС Π²Π°ΠΆΠ½ΠΎΠ΅: Π² Π½Π΅Π³ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Ρ‘Π½Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΡ‹ ΠΈ Π±ΡƒΠ΄Π΅ΠΌ ΠΌΠ΅Π½ΡΡ‚ΡŒ свойства ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ².

ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π½Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ alpha с Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ:

ValueAnimator animator = ValueAnimator.ofFloat(0, 1); 
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override 
   public void onAnimationUpdate(ValueAnimator animation) { 
       view.setAlpha((Float) animation.getAnimatedValue()); 
   } 
}); 
animator.start();

ObjectAnimator, наслСдуСтся ΠΎΡ‚ ValueAnimator

Π­Ρ‚ΠΎ класс, ΠΏΡ€ΠΈΠ·Π²Π°Π½Π½Ρ‹ΠΉ ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ с ValueAnimator. Π‘ Π½ΠΈΠΌ Π²Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π²Ρ€ΡƒΡ‡Π½ΡƒΡŽ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΊΠΎΠ΅-Π»ΠΈΠ±ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΎΠ±Ρ‹Ρ‚ΠΈΡŽ измСнСния β€” Π²Ρ‹ просто Π΄Π°Ρ‘Ρ‚Π΅ Animator’у ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚Π΅ ΠΏΠΎΠ»Π΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ scaleX. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Java Refliction ищСтся setter для этого поля (Π² Π΄Π°Π½Π½ΠΎΠΌ случаС β€” setScaleX. Π”Π°Π»Π΅Π΅ Animator ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠ΅Π½ΡΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ этого поля.

Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ObjectAnimator ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ alpha Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ Ρ‚Π°ΠΊ:

ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).start();

Π£ класса View Π΅ΡΡ‚ΡŒ нСсколько свойств ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Ρ… для анимирования с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Animator:

  • ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ (View.ALPHA)
  • ΠΌΠ°ΡΡˆΡ‚Π°Π± (View.SCALE_X, View.SCALE_Y)
  • Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ (View.ROTATION, View.ROTATION_X, View.ROTATION_Y)
  • ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ (View.X, View.Y, View.Z)
  • ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΠΎΠΉ части (View.TRANSLATION_X, View.TRANSLATION_Y, View.TRANSLATION_Z)

AnimatorSet (наслСдуСтся ΠΎΡ‚ Animator)

Π­Ρ‚ΠΎ класс, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ способами: Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΈΠ»ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΈ Ρ‚.Π΄.

ViewPropertyAnimator

Π­Ρ‚ΠΎ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ класс. Он Π½Π΅ наслСдуСтся ΠΎΡ‚ Animator, Π½ΠΎ ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ‚ Ρ‚ΠΎΠΉ ΠΆΠ΅ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ, Ρ‡Ρ‚ΠΎ ΠΈ ObjectAnimator для View, ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для Π»Ρ‘Π³ΠΊΠΎΠ³ΠΎ анимирования ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ View Π±Π΅Π· Π»ΠΈΡˆΠ½ΠΈΡ… Π·Π°ΠΌΠΎΡ€ΠΎΡ‡Π΅ΠΊ.

Π’ΠΎΡ‚ Ρ‚Π°ΠΊ с Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ alpha:

view.animate().alphaBy(0).alpha(1).start();

Как ΠΌΡ‹ Π½Π°Ρ‡Π°Π»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Animator

Около Π³ΠΎΠ΄Π° Π½Π°Π·Π°Π΄ ΠΏΠ΅Ρ€Π΅Π΄ΠΎ ΠΌΠ½ΠΎΠΉ встала Π·Π°Π΄Π°Ρ‡Π° ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈ ΠΊΠ»ΠΈΠΊΠ΅ Π½Π° элСмСнт. Π’ΠΎΡ‚ Ρ‚Π°ΠΊΡƒΡŽ:

355820622fb24674b809518a2004ca4e.gif


НС Ρ‚ΠΎ Ρ‡Ρ‚ΠΎΠ±Ρ‹ я Π½Π΅ Π΄Π΅Π»Π°Π» Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ ΠΏΡ€Π΅ΠΆΠ΄Π΅, Π½ΠΎ Π½Π° аутсорсС ΠΎΠ½ΠΈ Ρ€Π΅Π΄ΠΊΠΎ Π½ΡƒΠΆΠ½Ρ‹. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ я Π·Π°Π³ΡƒΠ³Π»ΠΈΠ» Animation Android. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ ΠΏΡΡ‚ΡŒ ссылок довольно ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описывали, ΠΊΠ°ΠΊ Π΄Π΅Π»Π°ΡŽΡ‚ΡΡ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ, ΠΈ я приступил. Π’ΠΎΡ‚ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

355820622fb24674b809518a2004ca4e.gif


Код Animation

 public static void likeAnimation(@DrawableRes int icon, 
                                     final ImageView imageView) { 
        imageView.setImageResource(icon); 
        imageView.setVisibility(View.VISIBLE); 
        AlphaAnimation showAlphaAnimation = new AlphaAnimation(0.0f, 1.0f); 
        showAlphaAnimation.setDuration(SHOW_DURATION); 
        ScaleAnimation showScaleAnimation = new ScaleAnimation(0.2f, 1.4f, 0.2f, 1.4f, 
                android.view.animation.Animation.RELATIVE_TO_SELF, 0.5f, 
                android.view.animation.Animation.RELATIVE_TO_SELF, 0.5f); 
        showScaleAnimation.setDuration(SHOW_DURATION); 
        AnimationSet showAnimationSet = new AnimationSet(false); 
        showAnimationSet.addAnimation(showAlphaAnimation); 
        showAnimationSet.addAnimation(showScaleAnimation); 
        showAnimationSet.setAnimationListener(new OnEndAnimationListener() { 
            @Override 
            public void onAnimationEnd(android.view.animation.Animation animation) { 
                ScaleAnimation toNormalScaleAnimation = new ScaleAnimation(1.4f, 1.0f, 1.4f, 1.0f, 
                        android.view.animation.Animation.RELATIVE_TO_SELF, 0.5f, 
                        android.view.animation.Animation.RELATIVE_TO_SELF, 0.5f); 
                toNormalScaleAnimation.setDuration(TO_NORMAL_DURATION); 
                toNormalScaleAnimation.setAnimationListener(new OnEndAnimationListener() { 
                    @Override 
                    public void onAnimationEnd(android.view.animation.Animation animation) { 
                        AlphaAnimation hideAlphaAnimation = new AlphaAnimation(1.0f, 0.0f); 
                        hideAlphaAnimation.setDuration(HIDE_DURATION); 
                        ScaleAnimation hideScaleAnimation = new ScaleAnimation(1.0f, 0.2f, 1.0f, 0.2f, 
                                android.view.animation.Animation.RELATIVE_TO_SELF, 0.5f, 
                                android.view.animation.Animation.RELATIVE_TO_SELF, 0.5f); 
                        hideScaleAnimation.setDuration(HIDE_DURATION); 
                        AnimationSet hideAnimationSet = new AnimationSet(false); 
                        hideAnimationSet.setStartOffset(HIDE_DELAY); 
                        hideAnimationSet.addAnimation(hideAlphaAnimation); 
                        hideAnimationSet.addAnimation(hideScaleAnimation); 
                        hideAnimationSet.setAnimationListener(new OnEndAnimationListener() { 
                            @Override 
                            public void onAnimationEnd(android.view.animation.Animation animation) { 
                                imageView.setVisibility(View.GONE); 
                            } 
                        }); 
                        imageView.startAnimation(hideAnimationSet); 
                    } 
                }); 
                imageView.startAnimation(toNormalScaleAnimation); 
            } 
        }); 
        imageView.startAnimation(showAnimationSet); 
    }

Бсылка Π½Π° ΠΊΠΎΠ΄

Код получился малопонятным, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄Ρ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΎ мСня ΠΊ поискам ΠΈΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° Π² составлСнии ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ. РСшСниС Π±Ρ‹Π»ΠΎ Π½Π°ΠΉΠ΄Π΅Π½ΠΎ Π½Π° StackOveflow. ИдСя такая: ΠΏΠΎΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ Π² AnimationSet со сдвигом, Ρ€Π°Π²Π½Ρ‹ΠΌ суммС Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚Π΅ΠΉ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ. ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ Π³ΠΎΡ€Π°Π·Π΄ΠΎ Π»ΡƒΡ‡ΡˆΠ΅, Ρ‡Π΅ΠΌ Π±Ρ‹Π»ΠΎ:

935d70fd173c465a9b1876a159bbe983.gif


AnimationSet:

 public static void likeAnimation(@DrawableRes int icon, 
                                     final ImageView imageView) { 
        imageView.setImageResource(icon); 
        imageView.setVisibility(View.VISIBLE); 
        AnimationSet animationSet = new AnimationSet(false); 
        animationSet.addAnimation(showAlphaAnimation()); 
        animationSet.addAnimation(showScaleAnimation()); 
        animationSet.addAnimation(toNormalScaleAnimation()); 
        animationSet.addAnimation(hideAlphaAnimation()); 
        animationSet.addAnimation(hideScaleAnimation()); 
        animationSet.setAnimationListener(new OnEndAnimationListener() { 
            @Override 
            public void onAnimationEnd(Animation animation) { 
                imageView.setVisibility(View.GONE); 
            } 
        }); 
        imageView.startAnimation(animationSet);
     } 
     private static Animation showAlphaAnimation() { 
        AlphaAnimation showAlphaAnimation = new AlphaAnimation(0.0f, 1.0f); 
        showAlphaAnimation.setDuration(SHOW_DURATION); 
        return showAlphaAnimation; 
    } 
     private static Animation showScaleAnimation() { 
        ScaleAnimation showScaleAnimation = new ScaleAnimation( 
                0.2f, 1.4f, 0.2f, 1.4f, 
                Animation.RELATIVE_TO_SELF, 0.5f, 
                Animation.RELATIVE_TO_SELF, 0.5f); 
        showScaleAnimation.setDuration(SHOW_DURATION); 
        return showScaleAnimation; 
    } 
     private static Animation toNormalScaleAnimation() { 
        ScaleAnimation toNormalScaleAnimation = new ScaleAnimation( 
                1.4f, 1.0f, 1.4f, 1.0f, 
                Animation.RELATIVE_TO_SELF, 0.5f, 
                Animation.RELATIVE_TO_SELF, 0.5f); 
        toNormalScaleAnimation.setDuration(TO_NORMAL_DURATION); 
        toNormalScaleAnimation.setStartOffset(SHOW_DURATION); 
        return toNormalScaleAnimation; 
    } 
     private static Animation hideAlphaAnimation() { 
        AlphaAnimation hideAlphaAnimation = new AlphaAnimation(1.0f, 0.0f); 
        hideAlphaAnimation.setDuration(HIDE_DURATION); 
        hideAlphaAnimation.setStartOffset(SHOW_DURATION + TO_NORMAL_DURATION + HIDE_DELAY); 
        return hideAlphaAnimation; 
    } 
     private static Animation hideScaleAnimation() { 
        ScaleAnimation hideScaleAnimation = new ScaleAnimation( 
                1.0f, 0.2f, 1.0f, 0.2f, 
                Animation.RELATIVE_TO_SELF, 0.5f, 
                Animation.RELATIVE_TO_SELF, 0.5f); 
        hideScaleAnimation.setDuration(HIDE_DURATION); 
        hideScaleAnimation.setStartOffset(SHOW_DURATION + TO_NORMAL_DURATION + HIDE_DELAY); 
        return hideScaleAnimation; 
    }

Бсылка Π½Π° ΠΊΠΎΠ΄

Код стал понятнСС ΠΈ Ρ‡ΠΈΡ‚Π°Π±Π΅Π»ΡŒΠ½Π΅Π΅, Π½ΠΎ Π΅ΡΡ‚ΡŒ ΠΎΠ΄Π½ΠΎ Β«Π½ΠΎΒ»: ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° сдвигом Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ довольно Π½Π΅ΡƒΠ΄ΠΎΠ±Π½ΠΎ Π΄Π°ΠΆΠ΅ Π² Ρ‚Π°ΠΊΠΎΠΉ простой ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Если Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΅Ρ‰Ρ‘ нСсколько шагов, Ρ‚ΠΎ это станСт ΠΏΠΎΡ‡Ρ‚ΠΈ Π½Π΅Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΠΌΠΎΠΉ Π·Π°Π΄Π°Ρ‡Π΅ΠΉ. Π’Π°ΠΊΠΆΠ΅ Π²Π°ΠΆΠ½Ρ‹ΠΌ минусом Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° стало странноС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ: Ρ€Π°Π·ΠΌΠ΅Ρ€ Π°Π½ΠΈΠΌΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ΠΏΠΎ нСпонятным для мСня ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°ΠΌ, Π±Ρ‹Π» большС, Ρ‡Π΅ΠΌ ΠΏΡ€ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ. ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠΈ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ Π½ΠΈ ΠΊ Ρ‡Π΅ΠΌΡƒ Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π»ΠΈ, Π° Π²Π½ΠΈΠΊΠ°Ρ‚ΡŒ Π³Π»ΡƒΠ±ΠΆΠ΅ я ΡƒΠΆΠ΅ Π½Π΅ стал β€” ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΌΠ½Π΅ всё Ρ€Π°Π²Π½ΠΎ Π½Π΅ нравился. Но я Ρ€Π΅ΡˆΠΈΠ» Ρ€Π°Π·Π²ΠΈΡ‚ΡŒ эту идСю ΠΈ Ρ€Π°Π·Π±ΠΈΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ шаг Π½Π° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ AnimatorSet. Π’ΠΎΡ‚ Ρ‡Ρ‚ΠΎ Π²Ρ‹ΡˆΠ»ΠΎ:

3a3bc5a293044c5684722d05bf552be1.gif


AnimatorSet Π² AnimatorSet

public static void likeAnimation(@DrawableRes int icon, 
                                     final ImageView imageView) { 
        imageView.setImageResource(icon); 
        imageView.setVisibility(View.VISIBLE); 
        AnimationSet animationSet = new AnimationSet(false); 
        animationSet.addAnimation(showAnimationSet()); 
        animationSet.addAnimation(toNormalAnimationSet()); 
        animationSet.addAnimation(hideAnimationSet()); 
        animationSet.setAnimationListener(new OnEndAnimationListener() { 
            @Override 
            public void onAnimationEnd(Animation animation) { 
                imageView.setVisibility(View.GONE); 
            } 
        }); 
        imageView.startAnimation(animationSet); 
    } 
     private static AnimationSet showAnimationSet() { 
        AlphaAnimation showAlphaAnimation = new AlphaAnimation(0.0f, 1.0f); 
        ScaleAnimation showScaleAnimation = new ScaleAnimation( 
                0.2f, 1.4f, 0.2f, 1.4f, 
                Animation.RELATIVE_TO_SELF, 0.5f, 
                Animation.RELATIVE_TO_SELF, 0.5f); 
        AnimationSet set = new AnimationSet(false); 
        set.addAnimation(showAlphaAnimation); 
        set.addAnimation(showScaleAnimation); 
        set.setDuration(SHOW_DURATION); 
        return set; 
    } 
     private static AnimationSet toNormalAnimationSet() { 
        ScaleAnimation toNormalScaleAnimation = new ScaleAnimation( 
                1.4f, 1.0f, 1.4f, 1.0f, 
                Animation.RELATIVE_TO_SELF, 0.5f, 
                Animation.RELATIVE_TO_SELF, 0.5f); 
        AnimationSet set = new AnimationSet(false); 
        set.addAnimation(toNormalScaleAnimation); 
        set.setDuration(TO_NORMAL_DURATION); 
        set.setStartOffset(SHOW_DURATION); 
        return set; 
    } 
     private static AnimationSet hideAnimationSet() { 
        AlphaAnimation hideAlphaAnimation = new AlphaAnimation(1.0f, 0.0f); 
        ScaleAnimation hideScaleAnimation = new ScaleAnimation( 
                1.0f, 0.2f, 1.0f, 0.2f, 
                Animation.RELATIVE_TO_SELF, 0.5f, 
                Animation.RELATIVE_TO_SELF, 0.5f); 
        AnimationSet set = new AnimationSet(false); 
        set.setDuration(HIDE_DURATION); 
        set.addAnimation(hideAlphaAnimation); 
        set.addAnimation(hideScaleAnimation); 
        set.setStartOffset(SHOW_DURATION + TO_NORMAL_DURATION + HIDE_DELAY); 
        return set; 
    }

Бсылка Π½Π° ΠΊΠΎΠ΄

НСкоррСктная Ρ€Π°Π±ΠΎΡ‚Π° Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ, ΠΏΠ»ΠΎΡ…ΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, всё ΠΏΠ»ΠΎΡ…ΠΎ. Π’Π½ΠΎΠ²ΡŒ я обратился ΠΊ Google, ΠΈ наткнулся Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Animation ΡƒΠΆΠ΅ являСтся Legacy code, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ устарСл ΠΈ Π½Π΅ поддСрТиваСтся, хотя ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ.
Π― понял, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ ΠΈΠ½Π°Ρ‡Π΅. И Π²ΠΎΡ‚ Π½Π° просторах Android Developers Ρ наткнулся Π½Π° Animator. ΠŸΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ с Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ выглядСла Ρ‚Π°ΠΊ:

d67ae74f22d34d0f8da4037229c95cf5.gif


Animator

public static void likeAnimation(@DrawableRes int icon, 
                                     final ImageView view) { 
        if (view != null && !isAnimate) { 
            AnimatorSet set = new AnimatorSet(); 
            set.playSequentially( 
                    showAnimatorSet(view), 
                    toNormalAnimatorSet(view), 
                    hideAnimatorSet(view)); 
            set.addListener(getLikeEndListener(view, icon)); 
            set.start(); 
        } 
        view.animate().alphaBy(0).alpha(1).start(); 
    } 
     private static AnimatorListenerAdapter getLikeEndListener(final ImageView view, final int icon) { 
        return new AnimatorListenerAdapter() { 
            @Override 
            public void onAnimationStart(Animator animation) { 
                super.onAnimationStart(animation); 
                isAnimate = true; 
                view.setVisibility(View.VISIBLE); 
                view.setImageResource(icon); 
                view.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
            } 
             @Override 
            public void onAnimationEnd(Animator animation) { 
                super.onAnimationEnd(animation); 
                isAnimate = false; 
                view.setVisibility(View.GONE); 
                view.setImageDrawable(null); 
                view.setLayerType(View.LAYER_TYPE_NONE, null); 
            } 
        }; 
    } 
     private static AnimatorSet showAnimatorSet(View view) { 
        AnimatorSet set = new AnimatorSet(); 
        set.setDuration(SHOW_DURATION).playTogether( 
                ObjectAnimator.ofFloat(view, View.ALPHA, 0f, 1f), 
                ObjectAnimator.ofFloat(view, View.SCALE_X, 0.2f, 1.4f), 
                ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.2f, 1.4f) 
        ); 
        return set; 
    } 
     private static AnimatorSet toNormalAnimatorSet(View view) { 
        AnimatorSet set = new AnimatorSet(); 
        set.setDuration(TO_NORMAL_DURATION).playTogether( 
                ObjectAnimator.ofFloat(view, View.SCALE_X, 1.4f, 1f), 
                ObjectAnimator.ofFloat(view, View.SCALE_Y, 1.4f, 1f) 
        ); 
        return set; 
    } 
     private static AnimatorSet hideAnimatorSet(View view) { 
        AnimatorSet set = new AnimatorSet(); 
        set.setDuration(HIDE_DURATION).playTogether( 
                ObjectAnimator.ofFloat(view, View.ALPHA, 1f, 0f), 
                ObjectAnimator.ofFloat(view, View.SCALE_X, 1f, 0.2f), 
                ObjectAnimator.ofFloat(view, View.SCALE_Y, 1f, 0.2f) 
        ); 
        set.setStartDelay(HIDE_DELAY); 
        return set; 
    }

Бсылка Π½Π° ΠΊΠΎΠ΄

Анимация Ρ€Π°Π±ΠΎΡ‚Π°Π»Π° Π±Π΅Π·ΡƒΠΏΡ€Π΅Ρ‡Π½ΠΎ, Π° Π·Π½Π°Ρ‡ΠΈΡ‚, поиски ΠΌΠΎΠΆΠ½ΠΎ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠΊΠΎΠ½Ρ‡Π΅Π½Π½Ρ‹ΠΌΠΈ. ЕдинствСнноС, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Animator Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Π½Π΅ Π·Π°ΠΏΡƒΡ‰Π΅Π½ Π»ΠΈ ΡƒΠΆΠ΅ ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ Animator для ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ view, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС старый ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ выполнятся, ΠΊΠ°ΠΊ Π½ΠΈ Π² Ρ‡Π΅ΠΌ Π½Π΅ Π±Ρ‹Π²Π°Π»ΠΎ.

Π“Π»ΡƒΠ±ΠΆΠ΅ Π² Animator

Π― Π½Π°Ρ‡Π°Π» поиски Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Π΅Ρ‰Ρ‘ интСрСсного ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Animator. ΠŸΠΎΠ»Ρ‘Ρ‚ мысли ΠΏΡ€ΠΈΠ²Ρ‘Π» мСня ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ:

a75a9b92a0e54275b1c4a92ba499f618.gif

ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ выполняСтся Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Animator’a:

  • ΠžΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΉ Π·Π°ΠΏΡƒΡΠΊ
AnimatorSet showHideSet = new AnimatorSet(); 
      showHideSet.playTogether( 
                ScrollAnimatorUtils.translationYAnimator(translationY, footerButtons), 
                ScrollAnimatorUtils.translationYAnimator(translationY, footerText), 
                ScrollAnimatorUtils.scrollAnimator(startScroll, endScroll, scrollView), 
                ScrollAnimatorUtils.alphaAnimator(1, 0, recyclerView) 
        ); 
        showHideSet.start();

1. Π΄Π²ΠΈΠ³Π°Π΅Ρ‚ Π²Π½ΠΈΠ· footer ΡΠΏΠΈΡΠΊΠ°;

2. Π΄Π²ΠΈΠ³Π°Π΅Ρ‚ Π²Π½ΠΈΠ· ΠΊΠ½ΠΎΠΏΠΊΠΈ.

  • translationYAnimator
 public static Animator translationYAnimator(final float start, int end, final View view, int duration) { 
        ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, end); 
        animator.setDuration(duration); 
        animator.addListener(new AnimatorListenerAdapter() { 
            @Override 
            public void onAnimationEnd(Animator animation) { 
                super.onAnimationEnd(animation); 
                view.setTranslationY(start); 
            } 
        }); 
        return animator; 
    }

3. скроллит ScrollView Π΄ΠΎ самого Π½ΠΈΠ·Π°;

  • scrollAnimator
public static Animator scrollAnimator(int start, int end, final View view, int duration) { 
        ValueAnimator scrollAnimator = ValueAnimator.ofInt(start, end); 
        scrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
            @Override 
            public void onAnimationUpdate(ValueAnimator valueAnimator) { 
                view.scrollTo(0, (int) valueAnimator.getAnimatedValue()); 
            } 
        }); 
        scrollAnimator.setDuration(duration); 
        scrollAnimator.addListener(getLayerTypeListener(view)); 
        return scrollAnimator; 
    }

4. Π½Π°ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π΅Ρ‚ alpha эффСкт Π½Π° recyclerView.

  • alphaAnimator
public static Animator alphaAnimator(int start, int end, View view, int duration) { 
        ValueAnimator alphaAnimator = ObjectAnimator.ofFloat(view, View.ALPHA, start, end); 
        alphaAnimator.setDuration(duration); 
        alphaAnimator.addListener(getLayerTypeListener(view)); 
        return alphaAnimator; 
    }

Бсылка Π½Π° ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄

Бсылка Π½Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π² Github

CΠΊΠΈΠ»Π»Ρ‹
Π§Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π·Π½Π°Ρ‚ΡŒ ΠΈ ΡƒΠΌΠ΅Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Android-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠΌ

Бписок Π±Π°Π·ΠΎΠ²Ρ‹Ρ… Π½Π°Π²Ρ‹ΠΊΠΎΠ², руководств, ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… статСй ΠΈ ΠΈΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΎΠ² для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰Π΅Π³ΠΎ Android-Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°

CΠΊΠΈΠ»Π»Ρ‹
14 сСнтября 2016
CannyViewAnimator β€” наша вСрсия ViewAnimator

БобствСнная Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ видимости View: описаниС, история создания ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹

CΠΊΠΈΠ»Π»Ρ‹
21 ноября 2016