AutoJs6 中文文档 下载 App

E4X 界面语法 — 用 XML 声明式写界面

什么是 E4X

E4X(ECMAScript for XML)是 JavaScript 的 XML 扩展,让你可以用类似 HTML 的语法在脚本中声明式地构建 Android 原生界面。AutoJs6 内置的 ui 模块就是基于 E4X 实现的。

// E4X 示例 —— 一个简单的登录界面
"ui"; // 声明这是 UI 脚本

ui.layout(
    <vertical padding="16">
        <text text="AutoJs6 示例应用" textSize="20sp" textColor="#333"/>
        <input id="username" hint="请输入用户名"/>
        <input id="password" hint="请输入密码" password="true"/>
        <button id="login" text="登录" w="*" h="auto"/>
    </vertical>
);

ui.login.click(() => {
    let name = ui.username.getText();
    let pwd = ui.password.getText();
    toast("登录: " + name);
});

基本结构

"ui" 声明

// 必须在脚本开头声明,告诉 AutoJs6 这是 UI 脚本
"ui";

ui.layout()

// 主界面布局 —— 在应用内全屏显示
ui.layout(
    <vertical>
        <text text="Hello"/>
    </vertical>
);

// 悬浮窗布局 —— 作为浮动按钮显示
ui.floatyWindow(
    <horizontal>
        <button text="A"/>
        <button text="B"/>
    </horizontal>
);

布局容器

vertical — 垂直排列

ui.layout(
    <vertical padding="16">
        <text text="第一行"/>
        <text text="第二行"/>
        <text text="第三行"/>
    </vertical>
);

horizontal — 水平排列

<horizontal>
    <button text="左"/>
    <button text="中"/>
    <button text="右"/>
</horizontal>

frame — 帧布局(子控件叠加)

<frame w="*" h="300">
    <img src="/sdcard/bg.png" w="*" h="*"/>
    <text text="覆盖在图片上" layout_gravity="center"/>
</frame>

RelativeLayout — 相对布局

<RelativeLayout w="*" h="*">
    <button id="btn1" text="按钮1" w="100" h="50"/>
    <button id="btn2" text="按钮2" 
        layout_below="btn1" 
        layout_toRightOf="btn1"/>
</RelativeLayout>

常用属性

宽高

// w = width, h = height
<button w="auto" h="auto"/>          // 自适应
<button w="*" h="auto"/>             // 撑满父容器宽度
<button w="200" h="50"/>             // 固定像素值
<button w="50dp" h="40dp"/>          // dp 单位
<button w="50%" h="auto"/>           // 百分比

padding 和 margin

<button padding="10">文字内边距</button>
<button margin="10">控件外边距</button>
<button paddingLeft="20" marginTop="10">分别设置</button>

文字属性

<text 
    text="显示的文字" 
    textSize="16sp"           // 字号
    textColor="#333333"       // 颜色
    textStyle="bold"          // 加粗
    gravity="center"          // 居中
    lines="2"                 // 最多 2 行
    ellipsize="end"           // 末尾省略
/>

背景

<button bg="#FF5722"/>                        // 纯色
<button bg="@drawable/bg_shape"/>            // drawable 资源
<button bg="gradient"/>                       // 预设渐变

控件 id 与事件绑定

用 id 获取控件引用

ui.layout(
    <vertical>
        <button id="myBtn" text="点我"/>
        <text id="result" text="等待点击..."/>
    </vertical>
);

// 通过 ui.控件id 获取引用
ui.myBtn.click(() => {
    ui.result.setText("按钮被点击了!");
});

事件类型

// 点击
ui.btn.click(() => {});

// 长按
ui.btn.longClick(() => {});

// 文本变化(输入框)
ui.input.on("change", (text) => {
    console.log("输入: " + text);
});

// 焦点变化
ui.input.on("focus", (hasFocus) => {
    console.log("焦点: " + hasFocus);
});

// 触摸事件
ui.btn.on("touch", (view, event) => {
    let x = event.getRawX();
    let y = event.getRawY();
});

常用控件

// 文本
<text text="内容"/>

// 按钮
<button text="按钮"/>

// 输入框
<input hint="提示文字" password="true"/>

// 图片
<img src="/sdcard/icon.png" w="50" h="50"/>

// 复选框
<checkbox text="同意条款" checked="false"/>

// 开关
<switch checked="true"/>

// 滑动条
<seekbar max="100" progress="50"/>

// 进度条
<progressbar max="100" progress="30"/>

// 滚动视图
<ScrollView h="*">
    <vertical>
        <text text="长文本..." textSize="14"/>
    </vertical>
</ScrollView>

// 列表(需要自定义适配器,较复杂)
// 简单场景用 ScrollView + vertical 代替

动态更新界面

"ui";

ui.layout(
    <vertical>
        <text id="counter" text="0" textSize="40sp" gravity="center"/>
        <button id="add" text="+1"/>
    </vertical>
);

let count = 0;
ui.add.click(() => {
    count++;
    ui.counter.setText(count.toString());
});

实战:简易计算器

"ui";

ui.layout(
    <vertical padding="20">
        <text id="display" text="0" textSize="40sp" w="*" gravity="right"/>
        <horizontal>
            <button text="7" onclick="calc('7')"/>
            <button text="8" onclick="calc('8')"/>
            <button text="9" onclick="calc('9')"/>
            <button text="/" onclick="calc('/')"/>
        </horizontal>
        <horizontal>
            <button text="4" onclick="calc('4')"/>
            <button text="5" onclick="calc('5')"/>
            <button text="6" onclick="calc('6')"/>
            <button text="*" onclick="calc('*')"/>
        </horizontal>
        <horizontal>
            <button text="1" onclick="calc('1')"/>
            <button text="2" onclick="calc('2')"/>
            <button text="3" onclick="calc('3')"/>
            <button text="-" onclick="calc('-')"/>
        </horizontal>
        <horizontal>
            <button text="0" onclick="calc('0')"/>
            <button text="." onclick="calc('.')"/>
            <button text="=" onclick="calc('=')"/>
            <button text="+" onclick="calc('+')"/>
        </horizontal>
    </vertical>
);

let expression = "";
function calc(input) {
    if (input === "=") {
        let result = eval(expression);
        ui.display.setText(result.toString());
        expression = result.toString();
    } else {
        expression += input;
        ui.display.setText(expression);
    }
}

调试技巧

实时预览

在 AutoJs6 中运行 UI 脚本时,界面会立即渲染显示。修改代码后重新运行即可看到更新。

查看控件属性

// 运行时检查控件状态
ui.layout(
    <button id="test" text="按钮" enabled="true"/>
);

console.log("文字: " + ui.test.text());
console.log("启用: " + ui.test.isEnabled());
console.log("可见: " + ui.test.isVisible());

多界面切换

// 定义多个界面
let mainUI = () => ui.layout(
    <vertical>
        <button id="goNext" text="下一页"/>
    </vertical>
);

let secondUI = () => ui.layout(
    <vertical>
        <text text="这是第二页"/>
    </vertical>
);

mainUI();
ui.goNext.click(() => secondUI());