手游SDK-动画

一、Dialog切换动画。

1、动画基础

Android 中的动画可以分为逐帧动画、补间动画、属性动画三类。

1)、逐帧动画

逐帧动画就是依次播放图片,每一帧都是一张图片。利用人眼视觉暂留的原理,实现动画。就如同平时的电影、动漫一样。
逐帧动画通常是采用XML资源进行定义,在 <animation-list …/> 标签下使用 <item …/> 子元素标签定义动画的全部帧,并指定各帧的持续时间。
在res/drawable下新建frame_animation.xml,并放入素材图片。

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
                  android:oneshot="true">
      <item android:drawable="@drawable/animation01" android:duration="50"/>
      <item android:drawable="@drawable/animation02" android:duration="50"/>
</animation-list>

其中android:oneshot控制动画是否循环播放。如果为true,动画将不会循环播放,否则该动画将会循环播放。
duration 为时间间隔,单位为毫秒。
将frame_animation.xml转换成AnimationDrawable对象。

frameAnim=(AnimationDrawable) getResources().getDrawable(R.drawable.frame_animation);
view.setBackgroundDrawable(frameAnim); //把动画设置为ImageView的背景

如果利用Java来实现
首先要创建AnimationDrawable对象

    animationDrawable = new AnimationDrawable();
    for (int i = 1; i < 9; i ++ ){
        int id = getResources().getIdentifier("animation0" + i, "drawable", getPackageName());
        Drawable drawable = getResources().getDrawable(id);
        animationDrawable.addFrame(drawable, 50);
    }
    animationDrawable.setOneShot(true);
    view.setBackgroundDrawable(animationDrawable);
2)、补间动画

补间动画就是指定动画开始、结束的关键帧。而动画变化的中间帧由系统计算补齐。
补件动画共有四种类型:TranslateAnimation-位移动画、ScaleAnimation-缩放动画、RotateAnimation-旋转动画、AlphaAnimation-透明度改变动画。还有一种AnimationSet-补间动画四种动画组合。
补间动画需要在res/anim/文件夹下定义动画资源。

alpha_anim.xml:透明度改变动画

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromAlpha="1.0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toAlpha="0.0" />

duration:持续时间,单位为毫秒。
fromAlpha 和 toAlpha:透明度
interpolator:插值器,主要作用是控制动画的变化速率,可以通过 @android:anim 来选择不同的插值器。

scale_anim.xml:缩放动画

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXScale="0.0"
    android:fromYScale="0.0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="1.0"
    android:toYScale="1.0"/>

pivot:参考点,值可以是float或者是百分比数值。
以 pivotX 为例,说明其取不同的值的含义:
10:距离动画所在view自身左边缘10像素
10% :距离动画所在view自身左边缘 的距离是整个view宽度的10%
10%p:距离动画所在view父控件左边缘的距离是整个view宽度的10%

translate_anim.xml:位移动画

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
      android:fromDegree="0"
      android:toDegree="1800"
      android:pivotX = "50%"
      android:pivotY="50%"
      android:duration = "3000"
/>

rotate_anim.xml:旋转动画

<?xml version="1.0" encoding="utf-8"?>
<rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="50%"
        android:pivotY="50%" />

最后使用loadAnimation将XML布局解析成Animation类。然后在控件中startAnimation,即可开启动画。

Animation animation = AnimationUtils.loadAnimation(this, R.xx.xxx);
// 开启动画
view.startAnimation(animation);
如果利用Java来实现

位移动画:

    Animation translateAnimation = new TranslateAnimation(05000500);
    translateAnimation.setDuration(3000);
    mButton.startAnimation(translateAnimation);

缩放动画:

    Animation scaleAnimation= new ScaleAnimation(0,2,0,2,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scaleAnimation.setDuration(3000);
    mButton.startAnimation(scaleAnimation);

旋转动画:

   Animation rotateAnimation = new RotateAnimation(0,270,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
   rotateAnimation.setDuration(3000);
   mButton.startAnimation(rotateAnimation);

透明度改变动画:

    Animation alphaAnimation = new AlphaAnimation(1,0);
    alphaAnimation.setDuration(3000);
    mButton.startAnimation(alphaAnimation);
3)、属性动画

属性动画,通过动态的改变对象的属性从而达到动画效果。
补间动画只是改变了View的显示效果而已,并不会真正的改变View的属性。而属性动画可以改变View的显示效果和属性。举个例子:例如屏幕左上角有一个Button按钮,使用补间动画将其移动到右下角,此刻你去点击右下角的Button,它是绝对不会响应点击事件的,因此其作用区域依然还在左上角。只不过是补间动画将其绘制在右下角而已,而属性动画则不会。

2、登陆界面的切换效果代码

切换效果为左右切换,点击后退时界面从左到右切入,下一步(注册,忘记密码等)时从右到左切入界面。
示例代码:

//viewCur为现在的view,viewNext为将要展示的view,isBack为是否后退
   protected void switchViewAnim(final View viewCur, final View viewNext, boolean isBack, boolean hasAnim) {
        if (viewNext == null && viewCur == null) {  //如果view全为null则返回
            return;
        }
        if(LoginDialog == null){
            return;
        }
        if (viewNext != null && viewCur == null) { //登录界面最后的界面,无需动画
            if (!hasAddView(viewNext)) {
                LoginDialog.addView(viewNext);
            }
            viewNext.setVisibility(View.VISIBLE);
            LoginDialog.post(new Thread() {
                @Override
                public void run() {
                    ViewBase viewBase = (ViewBase) viewNext.getTag();
                    requestFocus(viewBase);
                }
            });
            return;
        }
        if (viewNext == null && viewCur != null) { //登录界面的第一个界面,也无需动画
            if (!hasAddView(viewCur)) {
                LoginDialog.addView(viewCur);
            }
            viewCur.setVisibility(View.VISIBLE);
            LoginDialog.post(new Thread() {
                @Override
                public void run() {
                    ViewBase viewBase = (ViewBase) viewCur.getTag();
                    requestFocus(viewBase);
                }
            });
            return;
        }
        isAniming = true;


        int params[] = { 0, -1, 1, 0 }; //前进(动画)
        if (isBack) {
            params = new int[] { 0, 1, -1, 0 }; //后退(动画)
        }
        int duration = 250;//持续时间
        //设置动画效果
        TranslateAnimation taCur = new TranslateAnimation(Animation.RELATIVE_TO_SELF, params[0],
                Animation.RELATIVE_TO_SELF, params[1], Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
        TranslateAnimation taNext = new TranslateAnimation(Animation.RELATIVE_TO_SELF, params[2],
                Animation.RELATIVE_TO_SELF, params[3], Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
        taCur.setDuration(duration);
        taCur.setRepeatCount(0);
        taCur.setInterpolator(new LinearInterpolator());


        taNext.setDuration(duration);
        taNext.setRepeatCount(0);
        taNext.setInterpolator(new LinearInterpolator());


        taCur.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }


            @Override
            public void onAnimationEnd(Animation animation) {
                if(LoginDialog == null){
                    return;
                }
                LoginManager.getInstance().getLoginLayoutDialog().post(new Thread() {
                    @Override
                    public void run() {
                        viewCur.setVisibility(View.GONE);
                        ViewBase viewBase = (ViewBase) viewNext.getTag();
                        viewBase.onAnimEnd();
                        requestFocus(viewBase);
                    }
                });
            }


            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        });


        if (!hasAddView(viewCur)) {
            LoginDialog.addView(viewCur);
        }
        if (!hasAddView(viewNext)) {
            LoginDialog.addView(viewNext);
        }


        viewCur.clearAnimation();
        viewNext.clearAnimation();
        if (hasAnim) {
            viewCur.startAnimation(taCur);
            viewNext.startAnimation(taNext);
        } else {
            isAniming = false;
        }
        viewCur.setVisibility(hasAnim ? View.VISIBLE : View.GONE);
        viewNext.setVisibility(View.VISIBLE);
    }

主要使用位移动画TranslateAnimation来实现动画效果,利用参数isBack来确定使用何种动画。因为有back返回键,所以需要记录view的跳转,方便按返回时,返回上一个界面。

二、加载动画等

如果是一般APP,可以使用AVLoadingIndicatorView等第三方库,AVLoadingIndicatorView的使用还是比较简单的,而且加载动画的数量和效果也基本够用。但是我们这个是SDK,尽量不要引入第三方库,以避免和其他SDK或者APP起冲突。
在这里插入图片描述

如果对加载动画没特殊要求的,可以使用Android自带的ProgressBar进度条控件。
ProgressBar默认为圆形进度,循环转圈,不显示具体的进度值。
setVisibility:控制显示or隐藏
setIndeterminateDrawable:设置图片
ProgressBar也可以通过设置style="?android:attr/progressBarStyleHorizontal"变为横向进度条。
setProgress:可以设置具体的进度
在这里插入图片描述
在这里插入图片描述

如果不满足ProgressBar的效果,那可以通过自定义View来创建对应的加载动画。
自定义view的时候需要继承view并重写父类的onMeasure()、onLayout()、onDraw()三个方法。
measure:测量。系统会先根据xml布局文件和代码中对控件属性的设置,来获取或者计算出每个View和ViewGrop的尺寸,并将这些尺寸保存下来。
layout:布局。根据测量出的结果以及对应的参数,来确定每一个控件应该显示的位置。
draw:绘制。确定好位置后,就将这些控件绘制到屏幕上。

上一篇: 手游SDK-登录界面
下一篇: 手游SDK-支付

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值