You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Animated Vector Drawable 单向动画无法播放问题求助

Animated Vector Drawable 单侧动画无法触发问题修复

问题原因

  • 类型强转失败:AppCompat 组件加载的矢量动画默认是兼容库的 AnimatedVectorDrawableCompat 类,你代码中强转为系统原生的 AnimatedVectorDrawable,导致强转返回null,start() 方法没有执行。第一次动画能正常播放是因为页面初始化时系统刚好加载了原生类实例,第二次切换时强转失败就无法触发动画。
  • 资源匹配逻辑写反:当前代码中 isExpanded 为true时加载的是 ic_header_off_to_on,和常规的展开/收起切换逻辑对应关系相反,会导致动画表现不符合预期。
  • 监听器重复设置:你把 setOnClickListener 写在了点击触发的切换逻辑里,每次点击都会重复设置监听,属于无意义的冗余代码。

前置检查

首先确保module级build.gradle中已经开启矢量图兼容支持:

android {
    defaultConfig {
        // 开启矢量图兼容支持
        vectorDrawables.useSupportLibrary = true
    }
}

修复代码

将切换逻辑整合到点击监听中,统一使用兼容类加载动画实例:

// 页面初始化阶段执行,仅设置一次监听
image_header_toggle.setOnClickListener {
    isExpanded = !isExpanded
    // 根据状态选择对应动画资源,可根据实际交互调整判断条件
    val animRes = if (isExpanded) R.drawable.ic_header_on_to_off else R.drawable.ic_header_off_to_on
    // 加载兼容类动画实例,避免强转失败
    val animatedDrawable = AnimatedVectorDrawableCompat.create(requireContext(), animRes)
    image_header_toggle.setImageDrawable(animatedDrawable)
    // 启动动画
    animatedDrawable?.start()
}

优化建议(可选)

你当前做了两个方向的动画资源,其实可以只用一个动画资源,通过reverse()方法反向播放实现双向切换,减少包体积:

  1. 只保留ic_header_off_to_on.xml一个动画资源
  2. 代码修改为:
// 初始化阶段设置默认图标
image_header_toggle.setImageResource(R.drawable.ic_header_off_to_on)
image_header_toggle.setOnClickListener {
    isExpanded = !isExpanded
    val drawable = image_header_toggle.drawable as AnimatedVectorDrawableCompat
    if (isExpanded) {
        drawable.start()
    } else {
        drawable.reverse()
    }
}

内容的提问来源于stack exchange,提问作者24hg824g2g4gh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 13:12:02