【好玩的AOSP】没有UI设计师如何自制Android开机动画

近期学习进展

最近RedfinDemo应用开发基本停滞,一是工作繁忙,二是因为想要结合framework联动完成需求,不会C++是不行滴。所以在主攻C++的学习,又有大佬推荐《21天学通C++》,看了下果然简洁高效,编排合理。

在学习C++过程中还发现Kotlin的一些特性和C++很相似啊,比如自动类型推断,函数的语法糖,默认函数参数等等。Kotlin算是站在巨人的肩膀上,其也是一门优秀的语言,在Android领域被谷歌选为First的语言页不足为奇了。

玩点好玩的

学习C++之余,想把原生AOSP的开机动画给更新替换下,换换口味。

我们都知道,AOSP的默认开机动画是一个"ANDROID"的字样,配合一个渐变的底色动画。定制一个自己的开机动画,对于手机厂商来说,有利于宣传品牌,彰显企业文化。

像国内广为人知的定制系统,比如MIUI,ColorOS,FlymeOS等,都是没有直接使用默认动画的,定制了一套他们自己厂商的开机动画。而考虑到大厂都是人力充足,设计师,动效师,应有尽有。

(以下两张图片来自网络,如有侵权联系删除)

那像我这自己在下面玩玩源码的,没有设计师帮忙,该怎么搞一套看得过去的定制化的开机动画呢?

开始制作

从压缩包制作倒推流程

首先了解到,我们如果想要做开机动画的替换,需要准备一个bootanimation.zip的压缩包。

压缩包里面的文件格式一般比较固定:一个disc.txt,用来描述帧动画的播放策略和显示大小。若干个文件夹,里面是按照顺序命名的帧动画文件。像我的就是下面这个结构:

disc.txt里的文件内容格式也比较简单:

css 复制代码
364 830 15
p 1 0 part0

第一排364 830 15 ,依次表示:动画显示区域height高度364,width宽度830,帧数15

第二排p 1 0 part0 ,这个首个字母有三个可选:

kotlin 复制代码
p -- this part will play unless interrupted by the end of the boot
c -- this part will play to completion, no matter what
f -- same as p but in addition the specified number of frames is being faded out while continue playing. Only the first interrupted f part is faded out, other subsequent f parts are skipped

像p就表示直接全程播放,直到开机完成。第二位的1表示播放一次,如果是0就是循环播放。

第三位的0表示两帧图片之间间隔0ms,最后的part0表示这些帧动画在这个文件夹中。

文件写法明确了。难点在于如何搞到这些帧动画呢?

帧动画的制作

直接先展示制作路线:

Android应用里手动写一个简单的渐亮动画------>录屏------>MP4转PNG

我准备在Android应用里手写一个动画,在想办法转成png。

设计上力求简洁,用"Stephen OS"作为文案,也是做一个渐亮的表现形式。

方案定下来了,接下来随便新建一个demo项目。我找到一个免费字体Cooper Black,到应用xml里添加TextView控件,设置字体fontFamily:

ini 复制代码
 <TextView
        android:id="@+id/tv_animationtext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/cooper_black"
        android:rotation="90"
        android:alpha="0"
        android:text="Stephen OS"
        android:textColor="@color/white"
        android:textSize="88sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

因为我是Pixel 5 上刷的AOSP车机系统,所以开机时的屏幕方向还是vertical方向的,而我需要让其横向展示,所以在这个控件放置时直接旋转了90度。而且初始的透明度为0.

然后在Activity里准备写逻辑,顺手在工具类里写一个顶层扩展方法,给Activity设置强制全屏:

ini 复制代码
fun AppCompatActivity.setFullScreenMode() {
    val layoutParams = window.attributes
    layoutParams.layoutInDisplayCutoutMode =
        WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
    window.attributes = layoutParams
    window.setFlags(
        WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN
    )
    val uiOptions = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_FULLSCREEN)
    window.decorView.systemUiVisibility = uiOptions
}

动画编码为求简洁迅速,没有用传统的ValueAnimator,而是直接协程里使用repeat加delay,这种写法相当简单粗暴。

scss 复制代码
val logoText = rootView.findViewById<TextView>(R.id.tv_animationtext)
MainScope().launch {
     delay(2000L)
     repeat(255) {
          delay(7)
          infoLog(it.toString())
          logoText.alpha = (it / 255.0).toFloat()
     }
}

然后开启录屏软件,减去收尾,得到一个纯净的MP4,里面就是预计显示的开机动画了。

最后用到这样一个网站,可以将MP4转为png:Video to PNG image sequence converter

同样也是简单粗暴,免费版的功能已经够用了。

得到png后我们下载到本地,批量重命名成顺序的格式。将其放置到part0的文件夹中。准备和disc.txt一起打包。这里有一个坑,不可以直接用7zip打包成zip,最好使用winrar,压缩方式要选择存储:

集成到源码

压缩完成后,我们将bootanimation.zip放置到源码的某一个文件夹中。然后在你设备product的mk文件中,随意一个位置,加一句文件复制的指令:

ruby 复制代码
PRODUCT_COPY_FILES += \
<path-to-your-bootanimation.zip>:system/media/bootanimation.zip

在打包时,将这个zip包复制到ROM的system/media文件夹下,开机后android系统会搜索这个文件夹下有没有文件,有的话就优先播这个动画。

最后的成品

成品就像下面这样,一个大文字,从无到有渐亮的简单动画。感兴趣的独立开发者,也可以考虑考虑这种自制的方案。

相关推荐
B.-2 小时前
Flutter 应用在真机上调试的流程
android·flutter·ios·xcode·android-studio
有趣的杰克2 小时前
Flutter【04】高性能表单架构设计
android·flutter·dart
大耳猫7 小时前
主动测量View的宽高
android·ui
帅次10 小时前
Android CoordinatorLayout:打造高效交互界面的利器
android·gradle·android studio·rxjava·android jetpack·androidx·appcompat
枯骨成佛10 小时前
Android中Crash Debug技巧
android
工业互联网专业15 小时前
Python毕业设计选题:基于Django+uniapp的公司订餐系统小程序
vue.js·python·小程序·django·uni-app·源码·课程设计
程序员小海绵【vincewm】15 小时前
【设计模式】结合Tomcat源码,分析外观模式/门面模式的特性和应用场景
设计模式·tomcat·源码·外观模式·1024程序员节·门面模式
kim565916 小时前
android studio 更改gradle版本方法(备忘)
android·ide·gradle·android studio
咸芝麻鱼16 小时前
Android Studio | 最新版本配置要求高,JDK运行环境不适配,导致无法启动App
android·ide·android studio
无所谓จุ๊บ16 小时前
Android Studio使用c++编写
android·c++