Inicio > Android > Temas AOD en Miui

Temas AOD en Miui

martes, 6 de diciembre de 2022
Warning: Undefined variable $comments in /www/wwwroot/cristianvicente.com/wp-content/themes/inove/single.php on line 18
Dejar un comentario Ir a comentarios

En MIUI se puede escoger un tema en concreto para la función AOD de algunos terminales con animaciones e información. Si quieres fabricar el tuyo propio la documentación oficial es francamente escasa y la mayor parte en chino. Pero una vez consigues un ejemplo funcional el resto es relativamente fácil.

Según la documentación oficial, la estructura del fichero .mtz que tenemos que generar es la siguiente:

Básicamente se trata de un fichero ZIP (método de compresión deflate) al que se le ha cambiado la extensión por .MTZ que contiene un fichero «description.xml» como este:

<?xml version=’1.0′ encoding=’utf-8′ standalone=’yes’ ?>
<MIUI-Theme>
<title>Mi primer AOD</title>
<designer>Cristian</designer>
<author>Cristian</author>
<version>1.0</version>
<uiVersion>12</uiVersion>
<keywords></keywords>
</MIUI-Theme>

El fichero que aparece en el diagrama con el nombre «aod» es también un fichero ZIP (método de compresión deflate) al que se le ha quitado su extensión y que contiene una carpeta «content» y un fichero «aod_description.xml» como este:

<?xml version=’1.0′ encoding=’utf-8′ standalone=’yes’ ?>
<MIUI_Theme_Values>
<!– 类型;百变框架 maml_style –>
<theme_type>maml_style</theme_type>

<!– 是否支持显示农历开关;1 支持,0 不支持,默认为0 –>
<support_lunar_calendar>1</support_lunar_calendar>
<!– 是否支持显示电量开关 –>
<support_battery>1</support_battery>
<!– 是否支持显示通知开关 –>
<support_notification>1</support_notification>

<!– 开关初始状态:显示农历-关闭 –>
<lunar_calendar_enable>0</lunar_calendar_enable>
<!– 开关初始状态:显示电量-开启 –>
<battery_enable>1</battery_enable>
<!– 开关初始状态:显示通知-开启 –>
<notification_enable>1</notification_enable>

</MIUI_Theme_Values>

En el fichero anterior se definen ciertas opciones iniciales y capacidades de las que dispone nuestro tema.

Por otro lado, dentro de la carpeta «content» tenemos la implementación de nuestro AOD. En mi caso se ve así:

Lo interesante ocurre en el fichero «manifest.xml»:

<?xml version=»1.0″ encoding=»utf-8″?>
<Aod frameRate=»60″ screenWidth=»1080″ version=»1″ extraScales=»sw880-den440:0.8148,sw1860-den440:1″ extraResources=»sw880-den440::0.91,sw1860-den440::0.5323″>

<!– aod模块注意事项;1.动画触发放在下方 Trigger 中;2.动画时长不超过4s,超过部分将会被强制停止;3.动画仅播放一次,此后每分钟刷新一次时间 –>
<ExternalCommands>
<Trigger action=»init»>
<ExternCommand command=»animationState» strPara=»‘init'» />
</Trigger>
<Trigger action=»play»>
<AnimationCommand target=»aodAni» command=»play»/>
<AnimationCommand target=»hourAni» command=»play»/>
<AnimationCommand target=»minuteAni» command=»play»/>
</Trigger>
</ExternalCommands>

<VariableBinders>
<!– 查询通知 –>
<ContentProviderBinder name=»data» uri=»content://aod.notification/notifications» columns=»icon» countName=»hasnotifications»>
<Variable name=»notice_icon0″ type=»blob.bitmap» column=»icon» row=»0″/>
<Variable name=»notice_icon1″ type=»blob.bitmap» column=»icon» row=»1″/>
<Variable name=»notice_icon2″ type=»blob.bitmap» column=»icon» row=»2″/>
<Variable name=»notice_icon3″ type=»blob.bitmap» column=»icon» row=»3″/>
</ContentProviderBinder>
</VariableBinders>

<Var name=»aodAni»>
<VariableAnimation loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″/>
<AniFrame value=»1″ time=»1500″/>
</VariableAnimation>
</Var>
<Var name=»hourAni»>
<VariableAnimation loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″ />
<AniFrame value=»0″ time=»1000″ easeType=»CubicEaseOut»/>
<AniFrame value=»1″ time=»1500″/>
</VariableAnimation>
</Var>
<Var name=»minuteAni»>
<VariableAnimation name=»minuteAnimation» loop=»false» initPause=»true»>
<AniFrame value=»0″ time=»0″ />
<AniFrame value=»0″ time=»1200″ easeType=»CubicEaseOut»/>
<AniFrame value=»1″ time=»1700″/>
<Triggers>
<Trigger action=»end» condition=»#minuteAnimation.current_frame==-1″>
<!– 动画结束之后记得给系统发个命令 –>
<ExternCommand command=»animationState» strPara=»‘finish'» />
</Trigger>
</Triggers>
</VariableAnimation>
</Var>

<Image x=»540″ y=»360″ align=»center» alignV=»center» srcid=»#aodAni*12″ src=»img/num.webp» />
<Image x=»540″ y=»360″ align=»center» alignV=»center» pivotX=»18″ pivotY=»300″ rotation=»(#hourAni-1)*40+#hour12*30+#minute/2″ src=»hour.webp» alpha=»#hourAni*255″ />
<Image x=»540″ y=»360″ align=»center» alignV=»center» pivotX=»29″ pivotY=»300″ rotation=»(#minuteAni-1)*40+#minute*6″ src=»minute.webp» alpha=»#minuteAni*255″ />

<!– 时间 –>
<Group visibility=»eq(#time_format,0)» >
<DateTime x=»540″ y=»700″ format=»hh:mm» size=»110″ color=»#ffffff» align=»center» alignV=»center»/>
</Group>

<Var name=»es_week_xiaoxie» expression=»ifelse(eq(#day_of_week,1),’Domingo’,eq(#day_of_week,2),’Lunes’,eq(#day_of_week,3),’Martes’,eq(#day_of_week,4),’Miércoles’,eq(#day_of_week,5),’Jueves’,eq(#day_of_week,6),’Viernes’,’Sábado’)» type=»string»/>

<Var name=»es_month_jianxie» expression=»ifelse(eq(#month,0),’Enero’,eq(#month,1),’Febrero’,eq(#month,2),’Marzo’,eq(#month,3),’Abril’,eq(#month,4),’Mayo’,eq(#month,5),’Junio’,eq(#month,6),’Julio’,eq(#month,7),’Agosto’,eq(#month,8),’Septiembre’,eq(#month,9),’Octubre’,eq(#month,10),’Noviembre’,’Diciembre’)» type=»string»/>

<Group visibility=»eq(#time_format,1)»>
<DateTime x=»540″ y=»700″ format=»kk:mm» size=»110″ color=»#ffffff» align=»center» alignV=»center»/>
</Group>
<!– 日期、农历 –>
<Text x=»540″ y=»770″ color=»#ffffff» size=»32″ textExp=»@es_week_xiaoxie+’ ‘ +#day_of_week+’ de ‘+@es_month_jianxie+’ de ‘+#year» align=»center» bold=»true»/>
<Text x=»540″ y=»776″ color=»#ffffff» size=»32″ textExp=»@es_week_xiaoxie+’ ‘+#date+’ de ‘+@es_month_jianxie+’ de ‘ #year» align=»center» alignV=»bottom» bold=»true»/>
<!–<DateTime x=»540″ y=»776″ align=»center» alignV=»center» color=»#ffffffff» size=»40″ format=»M月d日 E» bold=»true»/>–>
<DateTime x=»540″ y=»830″ align=»center» alignV=»center» color=»#ffffffff» size=»40″ format=»YY年 N月e» bold=»true» visibility=»#lunar_calendar_enable»/>
<!– 电量 –>
<Group y=»886″ w=»1080″ h=»50″ alignV=»center» visibility=»#battery_enable»>
<Var name=»batteryColor» expression=»ifelse(#battery_state==1||#battery_state==3,’#ff4CB012′,’#ffffffff’)» type=»string» />
<Text x=»540″ y=»25″ align=»right» alignV=»center» color=»#ffffffff» size=»33″ textExp=»#battery_level+’%'» bold=»true»/>
<Rectangle x=»552″ y=»25″ w=»68″ h=»30″ alignV=»center» strokeColor=»#ffffffff» weight=»3″ strokeAlign=»inner» cornerRadius=»15″/>
<Group x=»558″ y=»25″ w=»0.56*#battery_level» h=»18″ alignV=»center» clip=»true»>
<Rectangle w=»56″ h=»18″ fillColor=»@batteryColor» cornerRadius=»9″/>
</Group>
<Image x=»558+28″ y=»25″ align=»center» alignV=»center» src=»lightning.png» visibility=»#battery_state==1||#battery_state==3″ />
</Group>

<!– 本地 预览模式 下显示几条通知;#preview_mode 是否为预览模式 –>
<Var name=»noticeCount» expression=»4″ type=»number» const=»true» />
<!– 通知 –>
<Group x=»ifelse(#preview_mode,-min(#noticeCount-1,3)*60,-min(#hasnotifications-1,3)*60)» visibility=»int(#notification_enable**#preview_mode) || #notification_enable»>
<Image name=»notice_icon0″ x=»540+120*0″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=1||#noticeCount}=1″ srcExp=»ifelse(#preview_mode,’noticeIcon/contacts.png’,»)» />
<Image name=»notice_icon1″ x=»540+120*1″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=2||#noticeCount}=2″ srcExp=»ifelse(#preview_mode,’noticeIcon/mms.png’,»)» />
<Image name=»notice_icon2″ x=»540+120*2″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=3||#noticeCount}=3″ srcExp=»ifelse(#preview_mode,’noticeIcon/email.png’,»)» />
<Image name=»notice_icon3″ x=»540+120*3″ y=»990″ w=»72″ h=»72″ align=»center» alignV=»center» visibility=»#hasnotifications}=4||#noticeCount}=4″ srcExp=»ifelse(#preview_mode,’noticeIcon/theme.png’,»)» />
</Group>

</Aod>

Al faltar documentación esta parte es la más complicada de sacar y la vas haciendo fijándote en temas ya hechos. En principio los fotogramas de la animación están separados y se ejecutan en bucle parándose en uno en concreto, con lo cual la imagen que obtendremos en el AOD no siempre corresponderá al mismo fotograma, lo que ayuda a mantener la salud de las pantallas AMOLED.

 

Categories: Android Tags: , ,
  1. martes, 5 de septiembre de 2023 a las 13:36 | #1

    I found this documentation, but only chinese:
    https://zhuti.designer.xiaomi.com/docs/grammar/#aod-%E6%81%AF%E5%B1%8F

    There are links for an AOD Editor.

  2. Cristian
    lunes, 12 de febrero de 2024 a las 08:23 | #2

    Warning: Undefined variable $array in /www/wwwroot/cristianvicente.com/wp-content/plugins/comment-connection/comment-connection.php on line 63

    Warning: Undefined variable $x in /www/wwwroot/cristianvicente.com/wp-content/plugins/comment-connection/comment-connection.php on line 63

    Warning: Trying to access array offset on null in /www/wwwroot/cristianvicente.com/wp-content/plugins/comment-connection/comment-connection.php on line 63

    @Nicola Inchingolo
    I was reading the documentation with Google Translate, but it is still not clear enough.


Warning: Undefined variable $user_ID in /www/wwwroot/cristianvicente.com/wp-content/themes/inove/comments.php on line 141