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

Android动画和Transition系列文章

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的创建主要有三种方式,而根本还是属性动画的定义,因此属性动画才是关键。

参考

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值