16

Aşağıdaki hareketli eylem düğmesi için animasyon ve renk değişimini taklit etmeye çalışıyorum.Animasyonlu Fab on (zoom in/out)

Yüzer eylem düğmesinin çalışma şekli beyazdır ve mavi yanar.

enter image description here

Ancak, animasyon ve rengini değiştirerek ile başarısız olmuştur.

Bunlar, bunu yapmak için denediğim tüm farklı yolları yorumladığımı görebildiğiniz gibi, bunu yapmak için benim girişimlerim olmuştur. herhangi bir öneriniz için

@SuppressWarnings("unused") 
    @OnClick(R.id.fabMovieFavourite) 
    public void addMovieFavourite(View view) { 
/*  final Animator animator = AnimatorInflater.loadAnimator(getActivity(), R.animator.add_favourite_movie); 
     animator.setTarget(view);) 
     animator.start(); 
*/ 
/* 
     AnimatorSet animatorSet = new AnimatorSet(); 
     PropertyValuesHolder propertyValuesHolderX = PropertyValuesHolder.ofFloat(View.SCALE_X, 1.1f); 
     PropertyValuesHolder propertyValuesHolderY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.1f); 
     ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, propertyValuesHolderX, propertyValuesHolderY); 
     objectAnimator.setDuration(300); 
     objectAnimator.setInterpolator(new OvershootInterpolator(10f)); 
*/ 

     /* 
     objectAnimator.setRepeatCount(1); 
     objectAnimator.setRepeatMode(ObjectAnimator.REVERSE); 
*/ 

/* 
     PropertyValuesHolder propertyValuesHolderX2 = PropertyValuesHolder.ofFloat(View.SCALE_X, 0.9f); 
     PropertyValuesHolder propertyValuesHolderY2 = PropertyValuesHolder.ofFloat(View.SCALE_Y, 0.9f); 
     ObjectAnimator objectAnimator2 = ObjectAnimator.ofPropertyValuesHolder(view, propertyValuesHolderX2, propertyValuesHolderY2); 
     objectAnimator.setDuration(300); 
     objectAnimator2.setInterpolator(new OvershootInterpolator(10f)); 

     animatorSet.playSequentially(objectAnimator, objectAnimator2); 
     objectAnimator.start(); 
*/ 

     // view.BackgroundTintList(ContextCompat.getColorStateList(getContext(), R.color.primary)); 
     //view.setBackgroundColor(ContextCompat.getColor(getActivity(), R.color.primary)); 

     if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) { 
      Timber.d("start translationZ"); 
      ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_Z, 12f); 
      objectAnimator.setDuration(300); 
      objectAnimator.setInterpolator(new OvershootInterpolator(10f)); 
      objectAnimator.setTarget(view); 
      objectAnimator.start(); 
     } 
    } 

Çok teşekkürler:

Bu

benim kodudur.

+0

ne çalışacaktı iki fabs kullanmaktır. kaybolur ve diğerini gösterirken birisini gizler. –

+0

@AngelKoh Sadece 1 fab kullanarak bir çözüm arıyorum – ant2009

+0

@ ant2009 iyi bir şey bu uygulamayı uygulamak isterseniz iyi bir kütüphane https://github.com/jd-alexander/LikeButton yardımıyla elde ettim .. .Bu yardımcı olabilir ... – PN10

cevap

45

Bu animasyonda iki aşama var. Birincisi X ve Y eksenini, ikincisini ise ölçekler. Böylece, onları iki AnimatorSet s'ye ayırabilir ve bunları sırayla çalabiliriz.

Animasyonun temel noktası, standart olanı olmadığından ikinci AnimatorSet için uygun enterpolator bulmaktır.

enter image description here

bakın, biz aşmasına fab istiyorum, sonra değip ve sonra nihayet animatör belirtilen değere kadar yerleşmek.

Neyse ki, Path ile birlikte bizim için bir interpolator yaratacak çok kullanışlı PathInterpolator var.

Path path = new Path(); 
path.moveTo(0.0f, 0.0f); 
path.lineTo(0.5f, 1.3f); 
path.lineTo(0.75f, 0.8f); 
path.lineTo(1.0f, 1.0f); 
PathInterpolator pathInterpolator = new PathInterpolator(path); 

Yani, ilk animasyon yapalım:

final float from = 1.0f; 
final float to = 1.3f; 

ObjectAnimator scaleX = ObjectAnimator.ofFloat(fab, View.SCALE_X, from, to); 
ObjectAnimator scaleY = ObjectAnimator.ofFloat(fab, View.SCALE_Y, from, to); 
ObjectAnimator translationZ = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, from, to); 

AnimatorSet set1 = new AnimatorSet(); 
set1.playTogether(scaleX, scaleY, translationZ); 
set1.setDuration(100); 
set1.setInterpolator(new AccelerateInterpolator()); 

set1.addListener(new AnimatorListenerAdapter() { 
    @Override 
    public void onAnimationEnd(Animator animation) { 
     fab.setImageResource(isActive ? R.drawable.heart_active : R.drawable.heart_passive); 
     fab.setBackgroundTintList(ColorStateList.valueOf(isActive ? colorActive : colorPassive)); 
     isActive = !isActive; 
    } 
}); 

Biz y hem x ölçeklendirme vardır. Ayrıca, uygun gölge efektine sahip olmak için z çevirisini değiştiriyoruz. Animasyon sona erdiğinde, fab durumunu (kalp rengi ve fab arka planı) değiştirmek istiyoruz.

Şimdi geri yerleşmek için animasyon oluşturmak alalım:

ObjectAnimator scaleXBack = ObjectAnimator.ofFloat(fab, View.SCALE_X, to, from); 
ObjectAnimator scaleYBack = ObjectAnimator.ofFloat(fab, View.SCALE_Y, to, from); 
ObjectAnimator translationZBack = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, to, from); 

AnimatorSet set2 = new AnimatorSet(); 
set2.playTogether(scaleXBack, scaleYBack, translationZBack); 
set2.setDuration(300); 
set2.setInterpolator(pathInterpolator); 

Buraya bakın, biz daha önce oluşturduğunuz pathInterpolator kullandı.

Biz bu iki AnimatorSet s sıralı oynamak istiyorum:

final AnimatorSet set = new AnimatorSet(); 
set.playSequentially(set1, set2); 

set.addListener(new AnimatorListenerAdapter() { 
    @Override 
    public void onAnimationEnd(Animator animation) { 
     fab.setClickable(true); 
    } 

    @Override 
    public void onAnimationStart(Animator animation) { 
     fab.setClickable(false); 
    } 
}); 

Ayrıca, bunu animasyon iken fab tıklamaları devre dışı bırakmak istediğiniz. Yani animasyon durumuna bağlı olarak açıyoruz/kapatıyoruz.Bir tıklama gerçekleştiğinde

Son olarak, animasyon başlatmak:

fab.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     set.start(); 
    } 
}); 

Sonucu:

enter image description here

Source code at github