Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
547 views
in Technique[技术] by (71.8m points)

java - How to Animate a Fab button (zoom in/out) continuously?

I Want to create this type of animation on FloatingActionButton

enter image description here

What I have tried

public void animFab() {

    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(500);
    set1.setInterpolator(new AccelerateInterpolator());

    set1.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {

        }
    });

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

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

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

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

    set.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            set.start();
        }
    });
    set.start();


}

The Problem

The Above code is working fine Lolipop and above device but not working in KitKat device

Below are some links I have tried

Can anyone help to solve the problem in KitKat device

If need more information please do let me know. Thanks in advance. Your efforts will be appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are seeing "Field requires API 21" Studio lint errors for the following lines of code the app aborts when running on Lollipop.

ObjectAnimator translationZ = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, from, to);
ObjectAnimator translationZBack = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, to, from);
PathInterpolator pathInterpolator = new PathInterpolator(path);

As you know, these features were introduced in API 21 and not available to earlier APIs and that's why you are seeing these errors. You can, however, get a path interpolator from the support library using PathInterpolatorCompat.

Helper for creating path-based [Interpolator](https://developer.android.com/reference/android/view/animation/Interpolator.html) instances. On API 21 or newer, the platform implementation will be used and on older platforms a compatible alternative implementation will be used.

I don't think that you will need a solution for the "z" translation. (I really don't see any difference between having it and not, but that could be just me. Anyway, the FAB already has a shadow for the height effect.)

Here is a rework of animFab() with some changes to accommodate APIs before 21. Make sure you snag the PathInterpolatorCompat from the v4 support library. First a video showing the code working on an API 19 emulator:

enter image description here

public void animFab() {  

    ObjectAnimator scaleX = ObjectAnimator.ofFloat(fab, View.SCALE_X, from, to);  
    ObjectAnimator scaleY = ObjectAnimator.ofFloat(fab, View.SCALE_Y, from, to);  
    AnimatorSet set1 = new AnimatorSet();  

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {  
        ObjectAnimator translationZ = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, from, to);  
        set1.playTogether(scaleX, scaleY, translationZ);  

    } else {  
        set1.playTogether(scaleX, scaleY);  
    }  
    set1.setDuration(500);  
    set1.setInterpolator(new AccelerateInterpolator());  
    set1.addListener(new AnimatorListenerAdapter() {  
        @Override  
  public void onAnimationEnd(Animator animation) {  

        }  
    });  

    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);  
    Interpolator pathInterpolator = PathInterpolatorCompat.create(path);  

    AnimatorSet set2 = new AnimatorSet();  
    ObjectAnimator scaleXBack = ObjectAnimator.ofFloat(fab, View.SCALE_X, to, from);  
    ObjectAnimator scaleYBack = ObjectAnimator.ofFloat(fab, View.SCALE_Y, to, from);  

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {  
        ObjectAnimator translationZBack = ObjectAnimator.ofFloat(fab, View.TRANSLATION_Z, to, from);  
        set2.playTogether(scaleXBack, scaleYBack, translationZBack);  
    } else {  
        set2.playTogether(scaleXBack, scaleYBack);  
    }  
    set2.setDuration(500);  
    set2.setInterpolator(pathInterpolator);  

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

    set.addListener(new AnimatorListenerAdapter() {  
        @Override  
  public void onAnimationEnd(Animator animation) {  
            super.onAnimationEnd(animation);  
            set.start();  
        }  
    });  
    set.start();  
}

Another possibility is to use AnimatedVectorDrawableCompat for the drawable animation, but that would be a complete rewrite.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...