纯xml实现较复杂的CheckBox/Switch动画

关键词:自定义View、属性动画、CheckBox、Switch、svg、Vector、矢量图

1、效果展示:

Switch

(🕹录制工具:scrcpy + GifCam.exe )

2、实现参考:

本文所有实现基于该参考文章,是一个实现的简化版本,强烈推荐阅读此文加深对xml动画的理解🤳:

Android 开发小记:自定义点击动画的 CheckBox 实现
maronyea.me/dev/304/

CheckBok

3、素材需求:

首先需要🎨UI提供svg的矢量图片,然后再用AndroidStudio导入为vector.xml,当然同时要理解vector中各个元素的含义才能为实现动画做好基础。作为👴ui boy,手搓👌android矢量图也是必备技能之一(bushi:

Android 矢量图详解
www.cnblogs.com/sydmobile/p...

准备好checkbox的最基本的选中/未选中两种状态的vector:

ON

checkbox_on.xml

xml 复制代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="55.6dp"
    android:height="30.8dp"
    android:viewportWidth="83"
    android:viewportHeight="46">
  <path
      android:name="fill_unchecked"
      android:pathData="M23,3L63,3A20,20 0,0 1,83 23L83,23A20,20 0,0 1,63 43L23,43A20,20 0,0 1,3 23L3,23A20,20 0,0 1,23 3z"
      android:fillColor="#6F555555"/>

  <path
      android:name="fill_checked"
      android:pathData="M23,3L63,3A20,20 0,0 1,83 23L83,23A20,20 0,0 1,63 43L23,43A20,20 0,0 1,3 23L3,23A20,20 0,0 1,23 3z"
      android:fillColor="#9C27B0"
      android:fillAlpha="0"/>

  <group
    android:name="thumb_group"
    android:translateX="0">
    <path
        android:name="thumb"
        android:pathData="M23,23m-17,0a17,17 0,1 1,34 0a17,17 0,1 1,-34 0"
        android:fillColor="#ffffff"
        android:fillAlpha="0.8"/>
  </group>

</vector>

OFF

checkbox_off.xml

xml 复制代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="55.6dp"
    android:height="30.8dp"
    android:viewportWidth="83"
    android:viewportHeight="46">
  <path
      android:name="fill_checked"
      android:pathData="M23,3L63,3A20,20 0,0 1,83 23L83,23A20,20 0,0 1,63 43L23,43A20,20 0,0 1,3 23L3,23A20,20 0,0 1,23 3z"
      android:fillColor="#9C27B0"
      android:fillAlpha="1.0"/>

  <group
      android:name="thumb_group"
      android:translateX="40">
    <path
        android:name="thumb"
        android:pathData="M23,23m-17,0a17,17 0,1 1,34 0a17,17 0,1 1,-34 0"
        android:fillColor="#ffffff"
        android:fillAlpha="0.8"/>
  </group>

</vector>

4、动画分解:

有了矢量图后就可以通过android:name属性让图的一部分动起来,需要把动画拆解为两个步骤:

  • 📐thumb 平移:操控上一步得到的vector的thumb_group在x轴方向上移动,对应属性translateX
  • ✨背景颜色渐变:操控上一步得到的vector的fill_checked/fill_unchecked,把这部分的的透明度进行变化,对应属性fillAlpha

4.1、最顶层drawable.xml文件:

checkbox_ainmated_drawable.xml:

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!--勾选-->
    <item
        android:id="@+id/checked"
        android:state_checked="true"
        android:drawable="@drawable/checkbox_on" />

    <!--未勾选-->
    <item
        android:id="@+id/unchecked"
        android:drawable="@drawable/checkbox_off" />

    <!--未勾选过渡到已勾选-->
    <transition
        android:drawable="@drawable/transition_task_unchecked_checked"
        android:fromId="@id/unchecked"
        android:toId="@id/checked" />

    <!--已勾选过渡到未勾选-->
    <transition
        android:drawable="@drawable/transition_task_checked_unchecked"
        android:fromId="@id/checked"
        android:toId="@id/unchecked" />

</animated-selector>

4.2、动画transition_task.xml实现:

4.2.1、task1:把thumb从左向右平移,并且颜色由未选择到选择的过渡:

transition_task_unchecked_checked.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/checkbox_off">
    <target
        android:animation="@anim/task_fill_checked_a_unchecked_checked"
        android:name="fill_checked"/>

    <target
        android:animation="@anim/task_thumb_move_x_unchecked_checked"
        android:name="thumb_group" />
</animated-vector>

task_thumb_move_x_unchecked_checked.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="@integer/animation_duration"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:propertyName="translateX"
        android:valueFrom="0"
        android:valueTo="40"
        android:valueType="floatType" />
</set>

task_fill_checked_a_unchecked_checked.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="@integer/animation_duration"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:propertyName="fillAlpha"
        android:valueFrom="0"
        android:valueTo="1"
        android:valueType="floatType" />
</set>

4.2.2、task2:把thumb从右向左平移,并且颜色由选择到未选择的过渡:

transition_task_checked_unchecked.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="@integer/animation_duration"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:propertyName="translateX"
        android:valueFrom="40"
        android:valueTo="0"
        android:valueType="floatType" />
</set>

task_fill_checked_a_checked_unchecked.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="@integer/animation_duration"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:propertyName="translateX"
        android:valueFrom="0"
        android:valueTo="40"
        android:valueType="floatType" />
</set> 

task_fill_checked_a_unchecked_checked.xml

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="@integer/animation_duration"
        android:interpolator="@android:interpolator/accelerate_decelerate"
        android:propertyName="fillAlpha"
        android:valueFrom="1"
        android:valueTo="0"
        android:valueType="floatType" />
</set>

4.3、res目录结构如下

erlang 复制代码
res
├── anim
│   ├── task_fill_checked_a_checked_unchecked.xml
│   ├── task_fill_checked_a_unchecked_checked.xml
│   ├── task_thumb_move_x_checked_unchecked.xml
│   └── task_thumb_move_x_unchecked_checked.xml
├── drawable
│   ├── checkbox_ainmated_drawable.xml
│   ├── checkbox_off.xml
│   ├── checkbox_on.xml
│   ├── transition_task_checked_unchecked.xml
│   └── transition_task_unchecked_checked.xml
...

4.4、使用方式🎉

xml 复制代码
<CheckBox
    android:layout_width="55.6dp"
    android:layout_height="30.8dp"
    android:drawableStart="@drawable/checkbox_ainmated_drawable"
    android:button="@null"
    android:background="@android:color/transparent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"/>   
<!--
    android:button="@null" 去除原生thumb-
    android:background="@android:color/transparent" 去除原生水波纹
-->

5、总结

更多技巧请参考原博客实现,如果你有牛叉的建议欢迎发表锐评✔

相关推荐
Yang-Never1 小时前
Kotlin协程 -> Job.join() 完整流程图与核心源码分析
android·开发语言·kotlin·android studio
一笑的小酒馆7 小时前
Android性能优化之截屏时黑屏卡顿问题
android
懒人村杂货铺10 小时前
Android BLE 扫描完整实战
android
TeleostNaCl12 小时前
如何安装 Google 通用的驱动以便使用 ADB 和 Fastboot 调试(Bootloader)设备
android·经验分享·adb·android studio·android-studio·android runtime
fatiaozhang952713 小时前
中国移动浪潮云电脑CD1000-系统全分区备份包-可瑞芯微工具刷机-可救砖
android·网络·电脑·电视盒子·刷机固件·机顶盒刷机
2501_9159184114 小时前
iOS 开发全流程实战 基于 uni-app 的 iOS 应用开发、打包、测试与上架流程详解
android·ios·小程序·https·uni-app·iphone·webview
lichong95114 小时前
【混合开发】vue+Android、iPhone、鸿蒙、win、macOS、Linux之dist打包发布在Android工程asserts里
android·vue.js·iphone
Android出海14 小时前
Android 15重磅升级:16KB内存页机制详解与适配指南
android·人工智能·新媒体运营·产品运营·内容运营
一只修仙的猿14 小时前
毕业三年后,我离职了
android·面试
编程乐学14 小时前
安卓非原创--基于Android Studio 实现的新闻App
android·ide·android studio·移动端开发·安卓大作业·新闻app