16

다음 플로팅 동작 버튼의 애니메이션 및 색상 변경을 모방하려고합니다.클릭시 팹 애니메이션하기 (확대/축소)

플로팅 동작 버튼의 작동 방식은 흰색이며 파란색은 켜짐입니다.

enter image description here

그러나, 나는 애니메이션과 색상을 변경에 실패되었습니다.

나는 이것을 시도한 모든 다른 방법들을 주석으로 볼 수 있었기 때문에 이것들을 시도한 나의 시도들이었다. 어떤 제안에 대한

@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(); 
     } 
    } 

많은 감사 :

내 코드입니다.

+0

제가 시도를하려는 것은 두 개의 팹 사용하는 것입니다. 페이드 아웃하면서 하나를 숨기고 다른 하나는 보여줍니다. –

+0

@AngelKoh 방금 1 fab을 사용하여 솔루션을 찾고 있는데 – ant2009

+0

@ ant2009 잘 구현하려면 라이브러리 https://github.com/jd-alexander/LikeButton의 도움으로이 문제를 해결했습니다. 도와 드리겠습니다. ... 그것 ... – PN10

답변

45

이 애니메이션에는 2 단계가 있습니다. 첫 번째는 X 축과 Y 축의 축척을 조정하고 두 번째 축은 축을 축척합니다. 그래서 우리는 그들을 두 개의 AnimatorSet으로 나눌 수 있으며 순차적으로 재생할 수 있습니다.

애니메이션의 핵심은 두 번째 AnimatorSet에 적합한 보간자를 찾는 것입니다. 왜냐하면 표준 보간자가 아니기 때문입니다.

enter image description here

참조, 우리는 오버 슈트 팹하려면, 다음 언더 다음 마지막으로 애니메이션에 지정된 값까지 정착.

다행히도, PathInterpolator은 매우 편리합니다. 이는 Path으로 우리를위한 보간기를 만듭니다.

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); 

자, 최초의 애니메이션을 만들 수 있습니다 :

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; 
    } 
}); 

우리는 y를 모두 X를 확장하고 있습니다. 또한 적절한 그림자 효과를 얻기 위해 z 변환을 변경하고 있습니다. 애니메이션이 끝나면 팹 상태 (하트와 팹 배경의 색)를 변경하려고합니다.

이제 다시 정착 애니메이션을 만들 수 있습니다 :

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); 

여기를 참조하십시오, 우리는 우리가 이전에 만든 pathInterpolator을 사용했다.

우리는 두 AnimatorSet의 순차적으로 재생하려면 :

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); 
    } 
}); 

는 또한, 우리가 그것을 애니메이션 동안 팹에 대한 클릭을 해제합니다. 그래서 우리는 애니메이션 상태에 따라 그것을 켜고 끌 수 있습니다.클릭이 발생했을 때

마지막으로, 우리는 애니메이션을 시작 :

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

결과 :

enter image description here

Source code at github