• Android(Lollipop/5.0) Material Design(六) 自定义动画


    官网地址:https://developer.android.com/intl/zh-tw/training/material/animations.html


    动画在Material设计中,为用户与app交互反馈他们的动作行为和提供了视觉上的连贯性。Material主题为Buttons和Activity的过渡提供了一些默认的动画。在android5.0(api21)及以上,同意自己定义这些动画:

    · Touch feedback  触摸反馈

    · Circular Reveal  循环显示

    · Activity transitions  活动过渡

    · Curved motion       曲线运动

    · View state changes  视图状态变化

    Customize Touch Feedback  自己定义触摸反馈动画

    在Material设计中。触摸反馈提供了一种在用户与UI进行交互时 即时可视化的确认接触点。关于buttons默认的触摸反馈动画。使用了RippleDrawable类。用一个波纹(涟漪)效果在两种不同的状态间过渡。

    在多数情况下,你须要在view的xml定义中,定义它的背景:

    ?

    android:attr/selectableItemBackground                              有界限的波纹    

    ?android:attr/selectableItemBackgroundBorderless             延伸到view之外的波纹     note:该属性为api21加入

    或者,你能够用xml定义一个RippleDrawable类型的资源,并使用波纹属性。

    你能够指定一个颜色给RippleDrawable对象,以改变它的默认触摸反馈颜色,使用主题的android:colorControlHighlight属性。

    Use the Reveal Effect  使用展现效果

    ViewAnimationUtils.createCircularReveal()方法使您可以激活一个循环显示或隐藏一个视图。

    显示:

    // previously invisible view
    View myView = findViewById(R.id.my_view);
    
    // get the center for the clipping circle
    int cx = (myView.getLeft() + myView.getRight()) / 2;
    int cy = (myView.getTop() + myView.getBottom()) / 2;
    
    // get the final radius for the clipping circle
    int finalRadius = myView.getWidth();
    
    // create and start the animator for this view
    // (the start radius is zero)
    Animator anim =
        ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius);
    anim.start();

    隐藏

    // previously visible view
    final View myView = findViewById(R.id.my_view);
    
    // get the center for the clipping circle
    int cx = (myView.getLeft() + myView.getRight()) / 2;
    int cy = (myView.getTop() + myView.getBottom()) / 2;
    
    // get the initial radius for the clipping circle
    int initialRadius = myView.getWidth();
    
    // create the animation (the final radius is zero)
    Animator anim =
        ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0);
    
    // make the view invisible when the animation is done
    anim.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            myView.setVisibility(View.INVISIBLE);
        }
    });
    
    // start the animation
    anim.start();

    Customize Activity Transitions  定义Activity的过渡动画

    ·一个enter transition表示。Activity的进入场景。比方一个explode enter transition,表示Views的进入场景:飞快的从外部向屏幕中心移动。

    ·一个exit transition表示,Activity的离开场景。比方一个explode exit transition,表示Views的离开场景:从屏幕中心散开。

    ·一个share transition表示,在两个Activity间共享它们的activity transtion。

    比方,两个Activity有一个同样的图片,而位置和尺寸不同,使用changeImageTransform这个共享元素,能在Activity间平稳的转换和缩放图片。


    android5.0(api21)及以上,支持这些效果的transition(过渡):

    爆炸——移动视图或从场景中心。class Explode

    滑行——移动视图或从一个场景的边缘。class Slide

    淡入淡出——加入或从场景中删除视图通过改变其透明度。

    class Fade

    也支持这些共享元素(都有相应的class)转换:
      changeBounds ——View的布局的边界变化。
      changeClipBounds——View的裁剪边界变化。
      changeTransform——View的旋转、缩放边界变化
      changeImageTransform——目标图像的尺寸和缩放变化。
      当启用活动在你的应用程序转换,默认同一时候淡出淡入之间的过渡是激活进入和退出活动。

    Specify custom transitions 自己定义过渡动画

    首先须要在定义主题的style中,使用android:windowContentTransitions属性,声明使用transitions。也能够定义使用的Transitions:

    <?xmlversion="1.0"encoding="utf-8"?>

    <resources>

        <stylename="MyTheme"parent="@android:style/Theme.Material">

            <!-- enable window content transitions -->

            <itemname="android:windowContentTransitions">true</item>

            <!-- specify enter and exit transitions -->

            <itemname="android:windowEnterTransition">@android:transition/explode</item>

            <itemname="android:windowExitTransition">@android:transition/explode</item>

            <!-- specify shared element transitions -->

            <itemname="android:windowSharedElementEnterTransition">@android:transition/move</item>

            <itemname="android:windowSharedElementExitTransition">@android:transition/slide_top</item>

        </style>

    </resources>

    注:每一个transition的xml中定义的就是一组change的元素

    在代码中启用transitions:

    // inside your activity (if you did not enable transitions in your theme)
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    
    // set an exit transition
    getWindow().setExitTransition(new Explode());
    在代码中设置transitions的方法还有

    要想尽快进行transitions过渡,可在Activity中调用Window.setAllowEnterTransitionOverlap()

    Start an activity using transitions 使用过渡启动Activity

    假设你要启用transtions并设置为一个Activity的结束exit transtion,当你以例如以下方式启动还有一个Activity时。它将被激活:
    startActivity(intent,
                  ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
    当你在还有一个Activity中设置了enter transtion。在其启动时,它将被激活。想要disable transitions,那么在启动还有一个Activity时:

    startActivity(intent,null);  //传递null 的options bundle

    Start an activity with a shared element  使用一个共享元素启动Acitvity


    1.在主题中启用window content 

    2.在style中定义共享的过渡transitions

    3.定义transitions的xml资源  res/transition

    4.在layout中调用android:transitionName="" 设置第3步中定义的名字

    5.调用 ActivityOptions.makeSceneTransitionAnimation()生成对应的ActivityOptions对象。

    // get the element that receives the click event
    final View imgContainerView = findViewById(R.id.img_container);
    
    // get the common element for the transition in this activity
    final View androidRobotView = findViewById(R.id.image_small);
    
    // define a click listener
    imgContainerView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(this, Activity2.class);
            // create the transition animation - the images in the layouts
            // of both activities are defined with android:transitionName="robot"
            ActivityOptions options = ActivityOptions
                .makeSceneTransitionAnimation(this, androidRobotView, "robot");
            // start the new activity
            startActivity(intent, options.toBundle());
        }
    });
    在代码中能够用View.setTransitionName()来设置过渡动画

    当你要关闭第二个Activity时,要反转过渡动画,那么能够调用Activity.finishAfterTransition()方法,而不是Activity.finish()。

    Start an activity with multiple shared elements  用多共享元素启动Activity

    若两个Activity拥有不仅仅一个的共享元素,要在它们之间開始场景transition动画,在它们的layout中都要使用 android:transitionName (或在Activity中代码中调用View.setTransitionName() )来定义。并创建一个例如以下的 ActivityOptions 对象:

    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
            Pair.create(view1, "agreedName1"),
            Pair.create(view2, "agreedName2"));

    Use Curved Motion 使用曲线运动

    在Material设计中的动画。依赖于曲线的时间插入值和空间运动模式。在android5.0(api21)及以上,能够自己定义动画时间曲线和曲线运动模式。

    PathInterpolator类是一个新的基于贝塞尔曲线或路径对象的插入器。这个插入器指定了一个1 x1正方形运动曲线。它使用(0,0)为锚点,(1,1)为控制点,作为构造函数的參数。

    你也能够定义一个path interpolator的xml资源:

    <pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
        android:controlX1="0.4"
        android:controlY1="0"
        android:controlX2="1"
        android:controlY2="1"/>
    系统提供了三种主要的曲线,XML资源:

    • @interpolator/fast_out_linear_in.xml
    • @interpolator/fast_out_slow_in.xml
    • @interpolator/linear_out_slow_in.xml

    您能够用PathInterpolator对象作Animator.setInterpolator()方法的參数。

    ObjectAnimator类有新构造函数使您可以激活坐标沿着一个path同一时候使用两种或两种以上的属性。

    比方。例如以下的animator就使用了一个path 对象。来同一时候操作View的x和y属性:

    ObjectAnimator mAnimator;
    mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
    ...
    mAnimator.start();

    Animate View State Changes  视图状态改变动画


    StateListAnimator类同意您定义动画执行时视图的状态变化。

    以下的样例演示怎样在xml中定义一个StateListAnimator:

    <!-- animate the translationZ property of a view when pressed -->
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
      <item android:state_pressed="true">
        <set>
          <objectAnimator android:propertyName="translationZ"
            android:duration="@android:integer/config_shortAnimTime"
            android:valueTo="2dp"
            android:valueType="floatType"/>
            <!-- you could have other objectAnimator elements
                 here for "x" and "y", or other properties -->
        </set>
      </item>
      <item android:state_enabled="true"
        android:state_pressed="false"
        android:state_focused="true">
        <set>
          <objectAnimator android:propertyName="translationZ"
            android:duration="100"
            android:valueTo="0"
            android:valueType="floatType"/>
        </set>
      </item>
    </selector>
    在上例中,为一个View加入视图状态动画。定义了一个使用selector元素的xml资源。并赋给view的android:stateListAnimator属性。如要在代码中为View指定视图状态动画,可使用AnimationInflater.loadStateListAnimator()载入xml资源。并使用View.setStateListAnimator()将其指定给View。

    当你的主题继承了Material主题。button默认拥有了z动画。

    为了避免这样的行为在你的button。设置android:stateListAnimator属性值为null。

    AnimatedStateListDrawable类同意您创建图片以显示关联View的状态改变动画。一些系统的Widget。在5.0上默认使用这些动画。

    以下的样例显示了怎样定义一个AnimatedStateListDrawable作为XML资源:

    <!-- res/drawable/myanimstatedrawable.xml -->
    <animated-selector
        xmlns:android="http://schemas.android.com/apk/res/android">
    
        <!-- provide a different drawable for each state-->
        <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
            android:state_pressed="true"/>
        <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
            android:state_focused="true"/>
        <item android:id="@id/default"
            android:drawable="@drawable/drawableD"/>
    
        <!-- specify a transition -->
        <transition android:fromId="@+id/default" android:toId="@+id/pressed">
            <animation-list>
                <item android:duration="15" android:drawable="@drawable/dt1"/>
                <item android:duration="15" android:drawable="@drawable/dt2"/>
                ...
            </animation-list>
        </transition>
        ...
    </animated-selector>

    Animate Vector Drawables  矢量图片动画

    矢量图片是可伸缩而不失真的。

    AnimatedVectorDrawable类让你能使一个矢量图动起来。

    通常在三种xml定义动态的矢量图:

    ·使用<vector>元素的矢量图,在res/drawable/

    ·一个动态矢量图,使用<animated-vector>元素,在res/drawable/

    ·一个或多个object animator。使用<objectAnimator>元素。在res/animator/

    矢量图能够定义的属性元素有<group>和<path>,<group>定义了一个<path>的集合,或者子<group>。<path>定义绘制的路径。

    定义矢量图时。能够给<group>和<path>指定一个名字,示比例如以下:

    <!-- res/drawable/vectordrawable.xml -->
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:height="64dp"
        android:width="64dp"
        android:viewportHeight="600"
        android:viewportWidth="600">
        <group
            android:name="rotationGroup"
            android:pivotX="300.0"
            android:pivotY="300.0"
            android:rotation="45.0" >
            <path
                android:name="v"
                android:fillColor="#000000"
                android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
        </group>
    </vector>
    在矢量动画中,引用矢量图定义的名字:

    <!-- res/drawable/animvectordrawable.xml -->
    <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
      android:drawable="@drawable/vectordrawable" >
        <target
            android:name="rotationGroup"
            android:animation="@anim/rotation" />
        <target
            android:name="v"
            android:animation="@anim/path_morph" />
    </animated-vector>
    下面样例代表了一个 ObjectAnimator or AnimatorSet 对象:动作为旋转360度

    <!-- res/anim/rotation.xml -->
    <objectAnimator
        android:duration="6000"
        android:propertyName="rotation"
        android:valueFrom="0"
        android:valueTo="360" />

    以下的样例表示矢量图path从一个图形到还有一个。两种渐变路径必须一致:他们必须具有同样数量的命令和同样数量的每一个命令的參数:

    <!-- res/anim/path_morph.xml -->
    <set xmlns:android="http://schemas.android.com/apk/res/android">
        <objectAnimator
            android:duration="3000"
            android:propertyName="pathData"
            android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
            android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
            android:valueType="pathType" />
    </set>
    很多其它详见:AnimatedVectorDrawable.



  • 相关阅读:
    C# -- 使用缓冲区进行文件下载操作
    C# -- 使用ODBC连接数据库
    C# -- Quartz.Net入门案例
    C# -- LinkedList的使用
    ASP.NET -- 获取浏览器信息
    Windows -- 从注册表删除IE浏览器加载项
    C# -- FTP上传下载
    C# -- 使用Ping检查网络是否正常
    WinForm -- 为TextBox文本框添加鼠标右键菜单
    C# -- 使用Parallel并行执行任务
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4605431.html
Copyright © 2020-2023  润新知