安卓主题之动态锁屏制作概要

安卓主题有关动态锁屏制作的信息摘要

平台文档#

OPPO主题壁纸最全教程文档指引

注意事项#

  • 按钮:vivo中的Normal > Image不受Button的x、y影响
  • 时钟频率 :oppo使用**#oppo_clock** vivo使用**#time**。oppo使用time容易卡顿
  • 壁纸:oppo的11x5 67x30中default_lock_wallpaper_2400.jpg换成bg.jpg
  • 遮罩图片:Mask的x、y在荣耀主题(包xxx.hnt)中不受Group和父级Image的x、y影响

去除别名#

alias="([\u4e00-\u9fa5]*|\w)+(-|_|/|\|*)+([\u4e00-\u9fa5]*|\w*)"

代码片段#

解锁#

<Unlocker name="unlocker" alias="任意方向解锁控件">
    <StartPoint x="#touch_begin_x" y="#touch_begin_y" w="1" h="1" alias="解锁起点" visibility="1"/>
    <EndPoint x="ifelse(gt(#unlocker.move_dist,300),#touch_x,-1)" y="ifelse(gt(#unlocker.move_dist,300),#touch_y,-1)" w="1" h="1" alias="解锁终点" visibility="1"/>
</Unlocker>
<Unlocker alias="向上滑动解锁控件" name="unlocker">
    <StartPoint alias="起点" x="0" y="#touch_begin_y" w="#screen_width" h="1" visibility="1"/>
    <EndPoint alias="终点" x="0" y="ifelse(gt(-#unlocker.move_y,450),#touch_y,-1)" w="#screen_width" h="1" visibility="1"/>
</Unlocker>

oppo专属#

<SupportPictorialButton alias="乐划锁屏oppo必加" w="#sw" h="#sh">
    <Triggers>
        <Trigger action="up">
            <IntentCommand action="com.heytap.pictorial.action.START_PICTURE_MODE" category="android.intent.category.DEFAULT" package="com.heytap.pictorial" class="com.heytap.pictorial.ui.slide.PictorialSlideActivity" condition="gt(#touch_begin_x-#touch_x,250)"/>
        </Trigger>
    </Triggers>
</SupportPictorialButton>

手势滑动#

<Button alias="右滑按钮" w="#sw" h="#sh">
    <Triggers>
        <Trigger action="up">
            <VariableCommand name="display_type" expression="not(#display_type)" condition="ge(#touch_x-#touch_begin_x,200)"/>
        </Trigger>
    </Triggers>
</Button>

<Button alias="左右滑动监听" x="0" y="0" w="#sw" h="#sh">
    <Triggers>
        <Trigger action="up">
            <VariableCommand alias="右滑" name="display_type" expression="1" condition="ge(#touch_x-#touch_begin_x,200)*not(#display_type)"/>
            <VariableCommand alias="左滑" name="display_type" expression="0" condition="ge(#touch_begin_x-#touch_x,200)*#display_type"/>
        </Trigger>
    </Triggers>
</Button>

时钟#

<Group temp_type="series_images" src="time/time.png" alias="时间组" x="0" y="0" angle="0" rotation="0">
    <Image src="time/time.png" srcid="int(#hour_time/10)"/>
    <Image x="#time_w" y="0" src="time/time.png" srcid="int(#hour_time%10)"/>
    <Image x="#time_w*2+10" y="0" src="time/dot.png"/>
    <Image x="#time_w*2+40" y="0" src="time/time.png" srcid="int(#minute/10)"/>
    <Image x="#time_w*3+40" y="0" src="time/time.png" srcid="int(#minute%10)"/>
</Group>

年月日#

<Group alias="几月几日" x="0" y="0" temp_type="series_images" src="date/a.png" angle="0" rotation="0">
    <Image alias="十位|月" x="0" y="0" src="date/a.png" srcid="ifelse(le(digit(#month+1,2),0),0,digit(#month+1,2))" />
    <Image alias="个位|月" x="#date_w" y="0" src="date/a.png" srcid="digit(#month+1,1)" />
    <Image alias="_月" x="#date_w*2+2" y="0" src="date/dota.png" />
    <Image alias="十位|日" x="#date_w*2+34+2" y="0" src="date/a.png" srcid="ifelse(le(digit(#date,2),0),0,digit(#date,2))" />
    <Image alias="个位|日" x="#date_w*3+34+2" y="0" src="date/a.png" srcid="digit(#date,1)" />
    <Image alias="_日" x="#date_w*4+34+4" y="0" src="date/dotb.png" />
</Group>

星期#

<Image alias="星期几" x="0" y="0" temp_type="series_images" src="week/b.png" srcid="#day_of_week"/>

电量#

<Group alias="电量数字" temp_type="series_images" src="date/a.png" x="-308-ifelse(le(digit(#battery_num,3),0)*gt(digit(#battery_num,2),0),24,le(digit(#battery_num,3),0)*le(digit(#battery_num,2),0),24*2,0)" y="1024+ifelse(le(digit(#battery_num,3),0)*gt(digit(#battery_num,2),0),4,le(digit(#battery_num,3),0)*le(digit(#battery_num,2),0),4*2,0)">
    <Image alias="百位" src="date/a.png" srcid="ifelse(le(digit(#battery_num,3),0),10,digit(#battery_num,3))"/>
    <Image alias="十位" x="24" y="-4" src="date/a.png" srcid="ifelse(le(digit(#battery_num,3),0)*le(digit(#battery_num,2),0),10,digit(#battery_num,2))"/>
    <Image alias="个位" x="24*2" y="-4*2" src="date/a.png" srcid="digit(#battery_num,1)"/>
    <Image x="24*3" y="-4*3" src="date/dotc.png" align="left" alignV="top"/>
</Group>

变量#

生日#

<!-- 生日 -->
  <Var alias="生日年" name="bday_year" expression="2023" persist="true"/>
  <Var alias="生日月" name="bday_month" expression="1" persist="true"/>
  <Var alias="生日日期" name="bday_day" expression="1" persist="true"/>
  <Var alias="生日生肖" name="bday_day_sx" expression="ifelse(eq((#bday_year-3)%12,0),12,(#bday_year-3)%12)" persist="true"/>

  <!-- 根据月份和日期返回星座序号 -->
  <VarArray alias="星座图片序号" type="number">
    <Vars>
      <Var name="xz_array" index="#bday_month-1"/>
    </Vars>
    <Items>      <!-- 1 -->
      <Item expression="ifelse(gt(#bday_day,19),11,10)"/>
      <!-- 2 -->
      <Item expression="ifelse(gt(#bday_day,18),12,11)"/>
      <!-- 3 -->
      <Item expression="ifelse(gt(#bday_day,20),1,12)"/>
      <!-- 4 -->
      <Item expression="ifelse(gt(#bday_day,19),2,1)"/>
      <!-- 5 -->
      <Item expression="ifelse(gt(#bday_day,20),3,2)"/>
      <!-- 6 -->
      <Item expression="ifelse(gt(#bday_day,21),4,3)"/>
      <!-- 7 -->
      <Item expression="ifelse(gt(#bday_day,22),5,4)"/>
      <!-- 8 -->
      <Item expression="ifelse(gt(#bday_day,22),6,5)"/>
      <!-- 9 -->
      <Item expression="ifelse(gt(#bday_day,22),7,6)"/>
      <!-- 10 -->
      <Item expression="ifelse(gt(#bday_day,23),8,7)"/>
      <!-- 11 -->
      <Item expression="ifelse(gt(#bday_day,20),9,8)"/>
      <!-- 12 -->
      <Item expression="ifelse(gt(#bday_day,21),10,9)"/>
    </Items>
  </VarArray>


  <Var alias="生日星座" name="bday_day_xz" expression="#xz_array"/>

  <Var alias="生日年是否闰年变量" name="bday_leap_year" expression="eq((#bday_year%4),0)*ne((#bday_year%100),0)+eq((#bday_year%400),0)"/>
  <Var alias="生日月是否闰月变量" name="bday_leap_month" expression="ifelse(#bday_leap_year,29,28)" />
  <Var alias="距生日所在月份有几天" name="bday_month_day" expression="ifelse(eq(#bday_month,2),31,eq(#bday_month,3),31+#bday_leap_month,eq(#bday_month,4),62+#bday_leap_month,eq(#bday_month,5),92+#bday_leap_month,eq(#bday_month,6),123+#bday_leap_month,eq(#bday_month,7),153+#bday_leap_month,eq(#bday_month,8),184+#bday_leap_month,eq(#bday_month,9),215+#bday_leap_month,eq(#bday_month,10),245+#bday_leap_month,eq(#bday_month,11),276+#bday_leap_month,eq(#bday_month,12),306+#bday_leap_month,0)"/>
  <Var alias="距生日共有几天" name="bday_sum_day" expression="#bday_month_day+#bday_day"/>

  <Var alias="生日倒计时天数(生日月大于当前月|生日月等于当前月并生日大于等于日期?累计天-今年已过天:累计天+今年剩余天数)" name="bday_count_day" expression="ifelse(gt(#bday_month,#month+1)+eq(#bday_month,#month+1)*ge(#bday_day,#date),#bday_sum_day-#past_days,#bday_sum_day+#remaining_days)"/>

  <Var alias="生日星座文字宽度" name="bday_xz_w" expression="159"/>
  <Var alias="生日输入弹窗开关" name="bday_pop_switch" expression="0"/>

  <Var alias="生日8位序号" name="bday_index" expression="1" persist="true"/>

  <Var alias="1位" name="num_1" expression="10" persist="true"/>
  <Var alias="2位" name="num_2" expression="10" persist="true"/>
  <Var alias="3位" name="num_3" expression="10" persist="true"/>
  <Var alias="4位" name="num_4" expression="10" persist="true"/>

  <Var alias="5位" name="num_5" expression="10" persist="true"/>
  <Var alias="6位" name="num_6" expression="10" persist="true"/>

  <Var alias="7位" name="num_7" expression="10" persist="true"/>
  <Var alias="8位" name="num_8" expression="10" persist="true"/>

更新#

 <Var alias="每十秒更新" name="make_rand" expression="int(#second/10)" threshold="1">
     <Trigger>
         <VariableCommand name="rand_num1" expression="int(rand()*9)+1"/>
     </Trigger>
</Var>

熄屏亮屏#

<Var alias="亮屏或熄屏" name="sc_state" expression="1"/>

<ExternalCommands >
    <Trigger action="resume" alias="亮屏">
        <VariableCommand name="sc_state" expression="1"/>
    </Trigger>
    <Trigger action="pause" alias="熄屏">
        <VariableCommand name="sc_state" expression="0"/>
    </Trigger>
</ExternalCommands>

随机数#

<!-- 随机数 -->
<Var alias="随机数1" name="rand_num1" expression="int(rand()*13)+1"/>
<Var alias="随机数2" name="rand_num2" expression="int(rand()*13)+1"/>
<Var alias="随机数3" name="rand_num3" expression="int(rand()*13)+1"/>

<Var alias="随机x位置" name="rand_x" expression="int(rand()*#sw/2)"/>
<Var alias="随机正负数" name="rand_z_f" expression="ifelse(lt(rand(),0.5),-1,1)"/>

时钟频率和时序变量#

<!-- 时钟频率 -->
<Var alias="oppo时钟频率(与time类似)" name="oppo_clock">
    <VariableAnimation>
        <AniFrame value="0" time="0" />
        <AniFrame value="999999999" time="999999999" />
    </VariableAnimation>
</Var>
<!-- oppo使用#oppo_clock vivo使用#time -->
<Var alias="时钟频率" name="clock_time" expression="#time"/>

<!-- 时序变量 -->
<Var alias="sin震荡位移 -范围~+范围之间 sin(速度)*范围" name="sin_move" expression="sin(#clock_time/1000)"/>
<Var alias="cos震荡位移 -范围~+范围之间 cos(速度)*范围" name="cos_move" expression="cos(#clock_time/1000)"/>
<Var alias="宽度随时间位移 输出+向右-向左 位置校正-(速度微调+速度)%范围" name="sw_move" expression="#sw/2-(800+#clock_time/10)%#sw"/>
<Var alias="高度随时间位移 输出+向上-向下 位置校正-(速度微调+速度)%范围" name="sh_move" expression="#sh/2-(#clock_time/4)%#sh"/>

时间#

<!-- 时间 -->
<Var alias="当前小时时间" name="hour_time" expression="ifelse(eq(#time_format,0),#hour12,#hour24)" />
<Var alias="当前剩余小时" name="remaining_hour" expression="23-#hour24"/>
<Var alias="当前剩余分钟" name="remaining_minute" expression="59-#minute"/>
<Var alias="当前剩余秒" name="remaining_second" expression="60-#second"/>
<Var alias="今天剩余时间" name="remaining_time" expression="int((#remaining_hour*60*60+#remaining_minute*60+#remaining_second)/86400*100)"/>
<Var alias="是否闰年变量" name="leap_year" expression="eq((#year%4),0)*ne((#year%100),0)+eq((#year%400),0)"/>
<Var alias="是否闰月变量" name="leap_month" expression="ifelse(#leap_year,29,28)" />
<Var alias="今年已过去天数" name="past_days" expression="gt(#month+1,1)*31+(28+#lya)*gt(#month+1,2)+gt(#month+1,3)*31+gt(#month+1,4)*30+gt(#month+1,5)*31+gt(#month+1,6)*30+gt(#month+1,7)*31+gt(#month+1,8)*31+gt(#month+1,9)*30+gt(#month+1,10)*31+gt(#month+1,11)*30+gt(#month+1,12)*31+#date"/>
<Var alias="今年剩余天数" name="remaining_days" expression="365+#leap_year-#past_days"/>
<VarArray alias="当月最大天数" type="number">
    <Vars>
        <Var name="max_month" index="#month"/>
    </Vars>
    <Items>
        <Item alias="1" expression="31"/>
        <Item alias="2" expression="#leap_month"/>
        <Item alias="3" expression="31"/>
        <Item alias="4" expression="30"/>
        <Item alias="5" expression="31"/>
        <Item alias="6" expression="30"/>
        <Item alias="7" expression="31"/>
        <Item alias="8" expression="31"/>
        <Item alias="9" expression="30"/>
        <Item alias="10" expression="31"/>
        <Item alias="11" expression="30"/>
        <Item alias="12" expression="31"/>
    </Items>
</VarArray>
<Var alias="当月剩余" name="month_remaining_days" expression="#max_month-#date" />
<Var name="fd" expression="#day_of_week-(#date-1)%7+7*ifelse(#day_of_week-(#date-1)%7,0,1)" />

动画#

<Image alias="电子表时间:闪动动画" x="#time_w*2+10" y="20" src="time/dot.png" visibility="not(eq(#battery_state,2))">
    <AlphaAnimation>
        <Alpha a="0" time="0"/>
        <Alpha a="0" time="400"/>
        <Alpha a="255" time="800"/>
        <Alpha a="255" time="1000"/>
    </AlphaAnimation>
</Image>

<Var alias="顶部进入动画" name="top_enter_an">
    <VariableAnimation>
        <AniFrame value="-420" time="0"/>
        <AniFrame value="#top_space" time="400"/>
        <AniFrame value="#top_space" time="999999999"/>
    </VariableAnimation>
</Var>

<Var alias="底部部进入动画" name="bottom_enter_an">
    <VariableAnimation>
        <AniFrame value="#sh" time="0"/>
        <AniFrame value="#sh-#bottom_panel_h-#bottom_space" time="400"/>
        <AniFrame value="#sh-#bottom_panel_h-#bottom_space" time="999999999"/>
    </VariableAnimation>
</Var>

<Var alias="底部部退出动画" name="bottom_out_an">
    <VariableAnimation>
        <AniFrame value="#sh-#bottom_panel_h-#bottom_space" time="0"/>
        <AniFrame value="#sh" time="400"/>
        <AniFrame value="#sh" time="999999999"/>
    </VariableAnimation>
</Var>

特殊日期#

<Var alias="预见日年" name="meet_day_year" expression="2018" persist="true"/>
<Var alias="预见日月" name="meet_day_month" expression="10" persist="true"/>
<Var alias="预见日日期" name="meet_day_day" expression="17" persist="true"/>

<Var alias="预见序号" name="meet_day_index" expression="1" persist="true"/>
<Var alias="预见1位" name="meet_day_1" expression="10" persist="true"/>
<Var alias="预见2位" name="meet_day_2" expression="10" persist="true"/>
<Var alias="预见3位" name="meet_day_3" expression="10" persist="true"/>
<Var alias="预见4位" name="meet_day_4" expression="10" persist="true"/>

<Var alias="预见5位" name="meet_day_5" expression="10" persist="true"/>
<Var alias="预见6位" name="meet_day_6" expression="10" persist="true" />

<Var alias="预见7位" name="meet_day_7" expression="10" persist="true"/>
<Var alias="预见8位" name="meet_day_8" expression="10" persist="true" />

<Var alias="预见日是否闰年变量" name="meet_leap_year" expression="eq((#meet_day_year%4),0)*ne((#meet_day_year%100),0)+eq((#meet_day_year%400),0)"/>
<Var alias="预见日是否闰月变量" name="meet_leap_month" expression="ifelse(#meet_leap_year,29,28)" />
<Var alias="距预见日所在月份有几天" name="meet_month_day" expression="ifelse(eq(#meet_day_month,2),31,eq(#meet_day_month,3),31+#meet_leap_month,eq(#meet_day_month,4),62+#meet_leap_month,eq(#meet_day_month,5),92+#meet_leap_month,eq(#meet_day_month,6),123+#meet_leap_month,eq(#meet_day_month,7),153+#meet_leap_month,eq(#meet_day_month,8),184+#meet_leap_month,eq(#meet_day_month,9),215+#meet_leap_month,eq(#meet_day_month,10),245+#meet_leap_month,eq(#meet_day_month,11),276+#meet_leap_month,eq(#meet_day_month,12),306+#meet_leap_month,0)"/>
<Var alias="距预见日共有几天" name="meet_sum_day" expression="#meet_month_day+#meet_day_day"/>
<Var alias="预见时间累计" name="meet_day_count" expression="(#year-#meet_day_year)*365+#past_days-#meet_sum_day" />

其他#

<Var alias="字母位序号" name="word_index" expression="3" persist="true"/>
<Var alias="字母组编号" name="word_index_group" expression="1"/>
<Var alias="字母1位" name="word_1" expression="24" persist="true"/>
<Var alias="字母2位" name="word_2" expression="25" persist="true"/>

<Var alias="背景序号" name="bg_index" expression="0" persist="true"/>

<Var alias="面板网格0序号" name="grid_0_index" expression="1" persist="true"/>
<Var alias="面板网格1序号" name="grid_1_index" expression="1" persist="true"/>
<Var alias="面板网格2序号" name="grid_2_index" expression="1" persist="true"/>
<Var alias="面板网格3序号" name="grid_3_index" expression="4" persist="true"/>

代码差异#

按钮#

oppo#

按钮中的Normal > Image会继承button的x、y坐标位置,是相对坐标

<Button x="210" y="-498" w="170" h="170">
    <Triggers>
        <Trigger action="up">
            <ExternCommand command="unlock" />
        </Trigger>
    </Triggers>
    <Normal>
        <Image src="icon/iz.png"/>
    </Normal>
</Button>

vivo#

Button是绝对坐标,对Group是相对坐标

按钮中的Normal > Image不受Button的x、y坐标位置影响,需要独立设置相同坐标,但ButtonGroup的x、y坐标位置影响。

<Button x="210" y="-498" w="170" h="170">
    <Triggers>
        <Trigger action="up">
            <IntentCommand action="android.intent.action.MAIN" package="com.bbk.theme" class="com.bbk.theme.Theme"/>
            <ExternCommand command="unlock" />
        </Trigger>
    </Triggers>
    <Normal>
        <Image x="210" y="-498" src="icon/iz.png"/>
    </Normal>
</Button>

遮罩图片#

vivo、oppo#

图片中的遮罩是相对坐标。

Group Image的x、y坐标位置影响

<Group alias="ele_img" x="#sw/2-80" y="2090+110">
    <Image src="ele.png" x="-260+#battery_num/100*260" y="0" w="260" h="34" visibility="1">
        <Mask x="-260" y="0" src="ele2.png" align="absolute" visibility="1"/>
    </Image>
    <Image src="ele3.png" visibility="1"/>
</Group>

honor荣耀#

图片中的遮罩需要写绝对坐标,相对坐标失效。

图片中的遮罩不受Group Image的x、y坐标位置影响,absolute是相对整个屏幕计算的坐标

<Group alias="ele_img" x="#sw/2-80" y="2090+110">
    <Image src="ele.png" x="-260+#battery_num/100*260" y="0" w="260" h="34" visibility="1">
        <Mask x="#sw/2-80-260" y="2090+110" src="ele2.png" align="absolute" visibility="1"/>
    </Image>
    <Image src="ele3.png" visibility="1"/>
</Group>