Android动画特效

        通过前面的学习,我们已经基本掌握了如何在Android中使用各种不同的动画来实现各种酷炫的效果。然后在实际的项目中,各种优秀的UI设计光靠程序员是远远不够的,一个靠谱的美工也是非常重要的。

        下面给大家列举一些动画效果的实例,让大家熟悉如何通过Android的动画框架来创建赏心悦目的动画。

1.灵动菜单

        下图展示的是灵动菜单的效果图。

        Android动画特效_第1张图片

        当用户点击小红点后,弹出菜单,并带有一个缓存的过渡动画,这也是Google在MaterialDesgin中所强大的动画过渡效果,如图所示。

        Android动画特效_第2张图片

        那么这样一个动画效果是怎么实现的呢?首先,它具有用户交互性,所以肯定不能使用视图动画而必须使用属性动画。其次,只需要针对每个不同的按钮设置不同的动画,并设置相应的插值器就可以实现展开、合拢效果了。理清思路后,实现就比较简单了,这里以展开动画为例,代码如下所示。

    private void startAnimation(){
        ObjectAnimator animator0 = ObjectAnimator.ofFloat(menus.getChildAt(0), "alpha",1f,0.5f);
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(menus.getChildAt(1), "translationY",200f);
        ObjectAnimator animator1_1 = ObjectAnimator.ofFloat(menus.getChildAt(1), "alpha",0f,1f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(menus.getChildAt(2), "translationX",200f);
        ObjectAnimator animator2_1 = ObjectAnimator.ofFloat(menus.getChildAt(2), "alpha",0f,1f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(menus.getChildAt(3), "translationY",-200f);
        ObjectAnimator animator3_1 = ObjectAnimator.ofFloat(menus.getChildAt(3), "alpha",0f,1f);
        ObjectAnimator animator4 = ObjectAnimator.ofFloat(menus.getChildAt(4), "translationX",-200f);
        ObjectAnimator animator4_1 = ObjectAnimator.ofFloat(menus.getChildAt(4), "alpha",0f,1f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(1000);
        set.setInterpolator(new BounceInterpolator());
        set.playTogether(animator0,animator1,animator1_1,animator2,animator2_1,animator3,animator3_1,animator4,animator4_1);
        set.start();
        mFlag = false;
    }
    private void closeAnimation() {
        ObjectAnimator animator0 = ObjectAnimator.ofFloat(menus.getChildAt(0), "alpha",0.5f,1f);
        ObjectAnimator animator1_1 = ObjectAnimator.ofFloat(menus.getChildAt(1), "alpha",1f,0f);
        ObjectAnimator animator2_1 = ObjectAnimator.ofFloat(menus.getChildAt(2), "alpha",1f,0f);
        ObjectAnimator animator3_1 = ObjectAnimator.ofFloat(menus.getChildAt(3), "alpha",1f,0f);
        ObjectAnimator animator4_1 = ObjectAnimator.ofFloat(menus.getChildAt(4), "alpha",1f,0f);
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(menus.getChildAt(1), "translationY",0f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(menus.getChildAt(2), "translationX",0f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(menus.getChildAt(3), "translationY",0f);
        ObjectAnimator animator4 = ObjectAnimator.ofFloat(menus.getChildAt(4), "translationX",0f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(500);
        set.setInterpolator(new BounceInterpolator());
        set.playTogether(animator0,animator1,animator1_1,animator2,animator2_1,animator3,animator3_1,animator4,animator4_1);
        set.start();
        mFlag = true;
    }
        下面再为按钮点击事件即可完成整个功能。
        menu_default.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mFlag) {
                    startAnimation();
                } else {
                    closeAnimation();
                }
            }
        });

2.计时器动画

        通过这个实例,我们来熟悉下ValueAnimator的使用,要实现计时器的动画效果,方法有很多,这里只是为了演示ValueAnimator的效果,因而使用ValueAnimator来实现,程序运行效果如图所示。
        Android动画特效_第3张图片
        当用户点击后,数字会不断增加,如图所示。
         Android动画特效_第4张图片
        要完成以上两个效果是比较简单的,只需要借助ValueAnimator来实现数字的不断增加,并将值设置给TextView即可,代码如下所示。

    public void btnAdd(final View view) {
        ValueAnimator valueAnimator = ValueAnimator.ofInt(0,100);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                ((TextView)view).setText("$" + (Integer)animation.getAnimatedValue());
            }
        });
        valueAnimator.setDuration(10000);
        valueAnimator.start();
    }

3.下拉展开动画

        下面再来演示一个ValueAnimator的小例子,这个例子来源于一个群友的问题,他希望能实现一个这样的效果:当点击一个View的时候,显示下面隐藏的一个View,要实现这个功能,需要将View的visibility属性由gone设置为visible即可,但是这个过程是瞬间完成的,如何让View在显示时增加一个动画效果呢?要实现这样的效果,需要让隐藏的view的高度不断发生变化,但不是迅速增大到目标值。所以使用ValueAnimator来模拟这个过程。首先,写一个简单的布局,两个LinearLayout,一个显示,一个隐藏。



    
        

        
    

    
        

        
    

        为了区分两个不同的LinearLayout,我们给它设置了不同的背景颜色和显示文字。接下来,当点击上面的LinearLayout时,需要获取到隐藏的LinearLayout最终需要到达一个高度,即我们的目标值,通过布局文件中的dp值转化为像素值即可。
        mDensity = getResources().getDisplayMetrics().density;
        mHiddenViewMeasuredHeight = (int)(mDensity*40 + 0.5);
        40就是在XML文件中定义的布局高度。
        然后给这个过程增加一个动画效果,前面分析了,需要使用ValueAnimator来创建一个从0到目标值发生器,并由此来改变View的布局属性。
        final ValueAnimator valueAnimator = ValueAnimator.ofInt(start, end);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                layoutParams.height = value;
                view.setLayoutParams(layoutParams);
            }
        });
        通过这样一个简单的ValueAnimator,就可以非常方便地实现显示、隐藏地动画效果了,完整代码如下所示。
package test.chenj.study_chapter7_7;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

public class Main3Activity extends AppCompatActivity {

    private float mDensity;
    private int mHiddenViewMeasuredHeight;
    private LinearLayout hidden_view;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        hidden_view = (LinearLayout)findViewById(R.id.hidden_view);
        mDensity = getResources().getDisplayMetrics().density;
        mHiddenViewMeasuredHeight = (int)(mDensity*40 + 0.5);
    }

    public void btnClick(final View view) {
        if(hidden_view.getVisibility() == hidden_view.VISIBLE) {
            animateClose(hidden_view);
        } else {
            animateOpen(hidden_view);
        }
    }

    private void animateOpen(final View view) {
        view.setVisibility(View.VISIBLE);
        ValueAnimator animator = createDropAnimator(view,0,mHiddenViewMeasuredHeight);
        animator.start();
    }

    private void animateClose(final View view){
        int origHeight = view.getHeight();
        ValueAnimator animator = createDropAnimator(view,origHeight,0);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                view.setVisibility(View.GONE);
            }
        });
        animator.start();
    }

    private ValueAnimator createDropAnimator(final View view,int start,int end){
        final ValueAnimator valueAnimator = ValueAnimator.ofInt(start, end);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                layoutParams.height = value;
                view.setLayoutParams(layoutParams);
            }
        });
        return valueAnimator;
    }
}
        程序运行效果如图所示。
         Android动画特效_第5张图片
        当点击View时,会逐渐弹出下面隐藏的View,如图所示。
        Android动画特效_第6张图片

你可能感兴趣的:(android群英传笔记)