美文网首页JetpackAndroid专题Android应用开发那些事
让View跟随状态动起来——StateListAnimator

让View跟随状态动起来——StateListAnimator

作者: 星风雪雨 | 来源:发表于2019-04-01 10:02 被阅读4次

    StateListAnimator定义了一组动画,可以根据View drawable的状态进行不同的切换。所谓状态指的是state_pressed、state_enabled等这些状态。
    Android提供的drawable中,其中有一种就是selector,只不过那种是指定的图片,而StateListAnimator指定的动画。
    不说废话,先看下效果:

    StateListAnimator Demo

    使用StateListAnimator

    StateListAnimator主要就是定义不同状态下的动画,主要有三种方式可以实现:

    1. 完全xml定义动画以及设置
    2. xml定义动画+代码设置
    3. 代码定义动画以及设置

    下面分别介绍。

    xml定义动画以及设置

    在res/animator下创建动画文件,根标签selector,然后定义每种状态下的动画,demo中左上角的动画就是这么定义的,如下:

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_pressed="true">
            <set>
                <objectAnimator
                    android:duration="@android:integer/config_shortAnimTime"
                    android:propertyName="scaleX"
                    android:repeatCount="10"
                    android:repeatMode="restart"
                    android:valueFrom="1.0"
                    android:valueTo="1.5"
                    android:valueType="floatType"/>
                <objectAnimator
                    android:duration="@android:integer/config_shortAnimTime"
                    android:propertyName="scaleY"
                    android:repeatCount="10"
                    android:repeatMode="restart"
                    android:valueFrom="1.0"
                    android:valueTo="1.5"
                    android:valueType="floatType"/>
            </set>
        </item>
        <!-- the default, non-pressed state; set x and y size to 100% -->
        <item android:state_pressed="false">
            <set>
                <objectAnimator
                    android:duration="@android:integer/config_shortAnimTime"
                    android:propertyName="scaleX"
                    android:valueTo="1"
                    android:valueType="floatType"/>
                <objectAnimator
                    android:duration="@android:integer/config_shortAnimTime"
                    android:propertyName="scaleY"
                    android:valueTo="1"
                    android:valueType="floatType"/>
            </set>
        </item>
    </selector>
    

    主要定义了在按住状态下的缩放动画,重复10次;正常状态下恢复到正常状态。定义好了动画后,只需在xml中使用stateListAnimator进行设置,如下:

    <ImageView
            android:clickable="true"
            android:src="@drawable/pic_11"
            android:stateListAnimator="@animator/anim_list_state_scale"
            />
    

    需要注意的是,使用了state_pressed状态后,如果这个View默认是不支持点击的,比如自定义View、ImageView等,那么还需要添加clickable=true,不然是没有效果的,切记切记。

    xml定义动画+代码设置

    demo中右上的动画,就是这种方式,xml定义动画和上面一样,就不多bb了,代码设置如下:

            cardView.stateListAnimator=AnimatorInflater.loadStateListAnimator(this,R.animator.card_smooth_shadow)
    
    

    代码定义动画以及设置

    demo中心动的感觉就是通过这种方式设置的,纯代码定义动画。动画效果也是在按下去的时候进行一个无限循环的缩放,正常状态下恢复到正常状态。
    代码如下:

    val xPressedAnim = ObjectAnimator.ofFloat(ivLike, View.SCALE_X, 1.0f, 1.5f).apply {
                duration = 1000
                repeatMode = ValueAnimator.REVERSE
                repeatCount = ValueAnimator.INFINITE
            }
            val yPressedAnim = ObjectAnimator.ofFloat(ivLike, View.SCALE_Y, 1.0f, 1.5f).apply {
                duration = 1000
                repeatMode = ValueAnimator.REVERSE
                repeatCount = ValueAnimator.INFINITE
            }
            val xNormalAnim = ObjectAnimator.ofFloat(ivLike, View.SCALE_X, 1.0f).apply {
                duration = 1000
            }
            val yNormalAnim = ObjectAnimator.ofFloat(ivLike, View.SCALE_Y, 1.0f).apply {
                duration = 1000
            }
    
            val pressedAnim = AnimatorSet().apply {
                play(xPressedAnim).with(yPressedAnim)
            }
            val normalAnim = AnimatorSet().apply {
                play(xNormalAnim).with(yNormalAnim)
            }
            //这个不能少,否则没有效果
            ivLike.isClickable=true
            ivLike.stateListAnimator = StateListAnimator().apply {
                addState(intArrayOf(android.R.attr.state_pressed), pressedAnim)
            //负数表示该状态为false
             addState(intArrayOf(-android.R.attr.state_pressed), normalAnim)
            }
    

    代码其实挺简单的,StateListAnimator定义后,通过addState()指定某些方法下的动画,状态都是在android.R.attr.state_XXX下,每种状态有true或者false,如果需要加上false,需要在值前面加上负号就可以了,如上面的代码。

    总结

    StateListAnimator的创建主要有三种方式,而根本还是属性动画的定义,因此属性动画才是关键。

    参考

    关注我的技术公众号,不定期会有技术文章推送,不敢说优质,但至少是我自己的学习心得。微信扫一扫下方二维码即可关注:

    二维码

    相关文章

      网友评论

        本文标题:让View跟随状态动起来——StateListAnimator

        本文链接:https://www.haomeiwen.com/subject/oyembqtx.html