UI - 用户界面 2
# 文本控件: text
文本控件用于显示文本,可以控制文本的字体大小,字体颜色,字体等。
以下介绍该控件的主要属性和方法,如果要查看他的所有属性和方法,请阅读[TextView](http://www.zhdoc.net/android/reference/android/widget/TextView.html)。
## text
设置文本的内容。例如`text="一段文本"`。
## textColor
设置字体的颜色,可以是RGB格式的颜色(例如#ff00ff),或者颜色名称(例如red, green等),具体参见[颜色](#ui_颜色)。
示例, 红色字体:`<text text="红色字体" textColor="red"/>`
## textSize
设置字体的大小,单位一般是sp。按照Material Design的规范,正文字体大小为14sp,标题字体大小为18sp,次标题为16sp。
示例,超大字体: `<text text="超大字体" textSize="40sp"/>`
## textStyle
设置字体的样式,比如斜体、粗体等。可选的值为:
* bold 加粗字体
* italic 斜体
* normal 正常字体
可以用或("|")把他们组合起来,比如粗斜体为"bold|italic"。
例如,粗体:`<text textStyle="bold" textSize="18sp" text="这是粗体"/>
## lines
设置文本控件的行数。即使文本内容没有达到设置的行数,控件也会留出相应的宽度来显示空白行;如果文本内容超出了设置的行数,则超出的部分不会显示。
另外在xml中是不能设置多行文本的,要在代码中设置。例如:
```
"ui";
ui.layout(
<vertical>
<text id="myText" line="3">
</vertical>
)
//通过\n换行
ui.myText.setText("第一行\n第二行\n第三行\n第四行");
```
## maxLines
设置文本控件的最大行数。
## typeface
设置字体。可选的值为:
* `normal` 正常字体
* `sans` 衬线字体
* `serif` 非衬线字体
* `monospace` 等宽字体
示例,等宽字体: `<text text="等宽字体" typeface="monospace"/>`
## ellipsize
设置文本的省略号位置。文本的省略号会在文本内容超出文本控件时显示。可选的值为:
* `end` 在文本末尾显示省略号
* `marquee` 跑马灯效果,文本将滚动显示
* `middle` 在文本中间显示省略号
* `none` 不显示省略号
* `start` 在文本开头显示省略号
## ems
当设置该属性后,TextView显示的字符长度(单位是em),超出的部分将不显示,或者根据ellipsize属性的设置显示省略号。
例如,限制文本最长为5em: `<text ems="5" ellipsize="end" text="很长很长很长很长很长很长很长的文本"/>
## autoLink
控制是否自动找到url和电子邮件地址等链接,并转换为可点击的链接。默认值为“none”。
设置该值可以让文本中的链接、电话等变成可点击状态。
可选的值为以下的值以其通过或("|")的组合:
* `all` 匹配所有连接、邮件、地址、电话
* `email` 匹配电子邮件地址
* `map` 匹配地图地址
* `none` 不匹配 (默认)
* `phone` 匹配电话号码
* `web` 匹配URL地址
示例:`<text autoLink="web|phone" text="百度: http://www.baidu.com 电信电话: 10000"/>`
# 按钮控件: button
按钮控件是一个特殊的文本控件,因此所有文本控件的函数的属性都适用于按钮控件。
除此之外,按钮控件有一些内置的样式,通过`style`属性设置,包括:
* Widget.AppCompat.Button.Colored 带颜色的按钮
* Widget.AppCompat.Button.Borderless 无边框按钮
* Widget.AppCompat.Button.Borderless.Colored 带颜色的无边框按钮
这些样式的具体效果参见"示例/界面控件/按钮控件.js"。
例如:`<button style="Widget.AppCompat.Button.Colored" text="漂亮的按钮"/>`
# 输入框控件: input
输入框控件也是一个特殊的文本控件,因此所有文本控件的函数的属性和函数都适用于按钮控件。输入框控件有自己的属性和函数,要查看所有这些内容,阅读[EditText](http://www.zhdoc.net/android/reference/android/widget/EditText.html)。
对于一个输入框控件,我们可以通过text属性设置他的内容,通过lines属性指定输入框的行数;在代码中通过`getText()`函数获取输入的内容。例如:
```
"ui";
ui.layout(
<vertical padding="16">
<text textSize="16sp" textColor="black" text="请输入姓名"/>
<input id="name" text="小明"/>
<button id="ok" text="确定"/>
</vertical>
);
//指定确定按钮点击时要执行的动作
ui.ok.click(function(){
//通过getText()获取输入的内容
var name = ui.name.getText();
toast(name + "您好!");
});
```
效果如图:

除此之外,输入框控件有另外一些主要属性(虽然这些属性对于文本控件也是可用的但一般只用于输入框控件):
## hint
输入提示。这个提示会在输入框为空的时候显示出来。如图所示:

上面图片效果的代码为:
```
"ui";
ui.layout(
<vertical>
<input hint="请输入姓名"/>
</vertical>
)
```
## textColorHint
指定输入提示的字体颜色。
## textSizeHint
指定输入提示的字体大小。
## inputType
指定输入框可以输入的文本类型。可选的值为以下值及其用"|"的组合:
* `date` 用于输入日期。
* `datetime` 用于输入日期和时间。
* `none` 没有内容类型。此输入框不可编辑。
* `number` 仅可输入数字。
* `numberDecimal` 可以与number和它的其他选项组合,以允许输入十进制数(包括小数)。
* `numberPassword` 仅可输入数字密码。
* `numberSigned` 可以与number和它的其他选项组合,以允许输入有符号的数。
* `phone` 用于输入一个电话号码。
* `text` 只是普通文本。
* `textAutoComplete` 可以与text和它的其他选项结合, 以指定此字段将做自己的自动完成, 并适当地与输入法交互。
* `textAutoCorrect` 可以与text和它的其他选项结合, 以请求自动文本输入纠错。
* `textCapCharacters` 可以与text和它的其他选项结合, 以请求大写所有字符。
* `textCapSentences` 可以与text和它的其他选项结合, 以请求大写每个句子里面的第一个字符。
* `textCapWords` 可以与text和它的其他选项结合, 以请求大写每个单词里面的第一个字符。
* `textEmailAddress` 用于输入一个电子邮件地址。
* `textEmailSubject` 用于输入电子邮件的主题。
* `textImeMultiLine` 可以与text和它的其他选项结合,以指示虽然常规文本视图不应为多行, 但如果可以, 则IME应提供多行支持。
* `textLongMessage` 用于输入长消息的内容。
* `textMultiLine` 可以与text和它的其他选项结合, 以便在该字段中允许多行文本。如果未设置此标志, 则文本字段将被限制为单行。
* `textNoSuggestions` 可以与text及它的其他选项结合, 以指示输入法不应显示任何基于字典的单词建议。
* `textPassword` 用于输入密码。
* `textPersonName` 用于输入人名。
* `textPhonetic` 用于输入拼音发音的文本, 如联系人条目中的拼音名称字段。
* `textPostalAddress` 用于输入邮寄地址。
* `textShortMessage` 用于输入短的消息内容。
* `textUri` 用于输入一个URI。
* `textVisiblePassword` 用于输入可见的密码。
* `textWebEditText` 用于输入在web表单中的文本。
* `textWebEmailAddress` 用于在web表单里输入一个电子邮件地址。
* `textWebPassword` 用于在web表单里输入一个密码。
* `time` 用于输入时间。
例如,想指定一个输入框的输入类型为小数数字,为: `<input inputType="number|numberDecimal"/>`
## password
指定输入框输入框是否为密码输入框。默认为`false`。
例如:`<input password="true"/>`
## numeric
指定输入框输入框是否为数字输入框。默认为`false`。
例如:`<input numeric="true"/>`
## phoneNumber
指定输入框输入框是否为电话号码输入框。默认为`false`。
例如:`<input phoneNumber="true"/>`
## digits
指定输入框可以输入的字符。例如,要指定输入框只能输入"1234567890+-",为`<input digits="1234567890+-"/>`。
## singleLine
指定输入框是否为单行输入框。默认为`false`。您也可以通过`lines="1"`来指定单行输入框。
例如:`<input singleLine="true"/>`
# 图片控件: img
图片控件用于显示来自网络、本地或者内嵌数据的图片,并可以指定图片以圆角矩形、圆形等显示。但是不能用于显示gif动态图。
这里只介绍他的主要方法和属性,如果要查看他的所有方法和属性,阅读[ImageView](http://www.zhdoc.net/android/reference/android/widget/ImageView.html)。
## src
使用一个Uri指定图片的来源。可以是图片的地址(http://....),本地路径(file://....)或者base64数据("data:image/png;base64,...")。
如果使用图片地址或本地路径,Auto.js会自动使用适当的缓存来储存这些图片,减少下次加载的时间。
例如,显示百度的logo:
```
"ui";
ui.layout(
<frame>
<img src="https://www.baidu.com/img/bd_logo1.png"/>
</frame>
);
```
再例如,显示文件/sdcard/1.png的图片为 `<img src="file:///sdcard/1.png"/>`。
再例如,使base64显示一张钱包小图片为:
```
"ui";
ui.layout(
<frame>
<img w="40" h="40" src="data:image/png;base64,..."/>
</frame>
);
```
## tint
图片着色,其值是一个颜色名称或RGB颜色值。使用该属性会将图片中的非透明区域都涂上同一颜色。可以用于改变图片的颜色。
例如,对于上面的base64的图片: `<img w="40" h="40" tint="red" src="data:image/png;base64,..."/>`,则钱包图标颜色会变成红色。
## scaleType
控制图片根据图片控件的宽高放缩时的模式。可选的值为:
* `center` 在控件中居中显示图像, 但不执行缩放。
* `centerCrop` 保持图像的长宽比缩放图片, 使图像的尺寸 (宽度和高度) 等于或大于控件的相应尺寸 (不包括内边距padding)并且使图像在控件中居中显示。
* `centerInside` 保持图像的长宽比缩放图片, 使图像的尺寸 (宽度和高度) 小于视图的相应尺寸 (不包括内边距padding)并且图像在控件中居中显示。
* `fitCenter` 保持图像的长宽比缩放图片, 使图片的宽**或**高和控件的宽高相同并使图片在控件中居中显示
* `fitEnd` 保持图像的长宽比缩放图片, 使图片的宽**或**高和控件的宽高相同并使图片在控件中靠右下角显示
* `fitStart` 保持图像的长宽比缩放图片, 使图片的宽**或**高和控件的宽高相同并使图片在控件靠左上角显示
* `fitXY` 使图片和宽高和控件的宽高完全匹配,但图片的长宽比可能不能保持一致
* `matrix` 绘制时使用图像矩阵进行缩放。需要在代码中使用`setImageMatrix(Matrix)`函数才能生效。
默认的scaleType为`fitCenter`;除此之外最常用的是`fitXY`, 他能使图片放缩到控件一样的大小,但图片可能会变形。
## radius
图片控件的半径。如果设置为控件宽高的一半并且控件的宽高相同则图片将剪切为圆形显示;否则图片为圆角矩形显示,半径即为四个圆角的半径,也可以通过`radiusTopLeft`, `radiusTopRight`, `radiusBottomLeft`, `radiusBottomRight`等属性分别设置四个圆角的半径。
例如,圆角矩形的Auto.js图标:`<img w="100" h="100" radius="20" bg="white" src="http://www.autojs.org/assets/uploads/profile/3-profileavatar.png" />`
有关该属性的单位,参见[尺寸的单位: Dimension](#ui_尺寸的单位_Dimension)。
## radiusTopLeft
图片控件的左上角圆角的半径。有关该属性的单位,参见[尺寸的单位: Dimension](#ui_尺寸的单位_Dimension)。
## radiusTopRight
图片控件的右上角圆角的半径。有关该属性的单位,参见[尺寸的单位: Dimension](#ui_尺寸的单位_Dimension)。
## radiusBottomLeft
图片控件的左下角圆角的半径。有关该属性的单位,参见[尺寸的单位: Dimension](#ui_尺寸的单位_Dimension)。
## radiusBottomRight
图片控件的右下角圆角的半径。有关该属性的单位,参见[尺寸的单位: Dimension](#ui_尺寸的单位_Dimension)。
## borderWidth
图片控件的边框宽度。用于在图片外面显示一个边框,边框会随着图片控件的外形(圆角等)改变而相应变化。
例如, 圆角矩形带灰色边框的Auto.js图标:`<img w="100" h="100" radius="20" borderWidth="5" borderColor="gray" bg="white" src="http://www.autojs.org/assets/uploads/profile/3-profileavatar.png" />`
## borderColor
图片控件的边框颜色。
## circle
指定该图片控件的图片是否剪切为圆形显示。如果为`true`,则图片控件会使其宽高保持一致(如果宽高不一致,则保持高度等于宽度)并使圆形的半径为宽度的一半。
例如,圆形的Auto.js图标:`<img w="100" h="100" circle="true" bg="white" src="http://www.autojs.org/assets/uploads/profile/3-profileavatar.png" />`
# 垂直布局: vertical
垂直布局是一种比较简单的布局,会把在它里面的控件按照垂直方向依次摆放,如下图所示:
垂直布局:
—————
| 控件1 |
| 控件2 |
| 控件3 |
| ............ |
——————
## layout_weight
垂直布局中的控件可以通过`layout_weight`属性来控制控件高度占垂直布局高度的比例。如果为一个控件指定`layout_weight`, 则这个控件的高度=垂直布局剩余高度 * layout_weight / weightSum;如果不指定weightSum, 则weightSum为所有子控件的layout_weight之和。所谓"剩余高度",指的是垂直布局中减去没有指定layout_weight的控件的剩余高度。
例如:
```
"ui";
ui.layout(
<vertical h="100dp">
<text layout_weight="1" text="控件1" bg="#ff0000"/>
<text layout_weight="1" text="控件2" bg="#00ff00"/>
<text layout_weight="1" text="控件3" bg="#0000ff"/>
</vertical>
);
```
在这个布局中,三个控件的layout_weight都是1,也就是他们的高度都会占垂直布局高度的1/3,都是33.3dp.
再例如:
```
"ui";
ui.layout(
<vertical h="100dp">
<text layout_weight="1" text="控件1" bg="#ff0000"/>
<text layout_weight="2" text="控件2" bg="#00ff00"/>
<text layout_weight="1" text="控件3" bg="#0000ff"/>
</vertical>
);
```
在这个布局中,第一个控件高度为1/4, 第二个控件为2/4, 第三个控件为1/4.
再例如:
```
"ui";
ui.layout(
<vertical h="100dp" weightSum="5">
<text layout_weight="1" text="控件1" bg="#ff0000"/>
<text layout_weight="2" text="控件2" bg="#00ff00"/>
<text layout_weight="1" text="控件3" bg="#0000ff"/>
</vertical>
);
```
在这个布局中,因为指定了weightSum为5, 因此第一个控件高度为1/5, 第二个控件为2/5, 第三个控件为1/5.
再例如:
```
"ui";
ui.layout(
<vertical h="100dp">
<text h="40dp" text="控件1" bg="#ff0000"/>
<text layout_weight="2" text="控件2" bg="#00ff00"/>
<text layout_weight="1" text="控件3" bg="#0000ff"/>
</vertical>
);
```
在这个布局中,第一个控件并没有指定layout_weight, 而是指定高度为40dp, 因此不加入比例计算,此时布局剩余高度为60dp。第二个控件高度为剩余高度的2/3,也就是40dp,第三个控件高度为剩余高度的1/3,也就是20dp。
垂直布局的layout_weight属性还可以用于控制他的子控件高度占满剩余空间,例如:
```
"ui";
ui.layout(
<vertical h="100dp">
<text h="40dp" text="控件1" bg="#ff0000"/>
<text h="40dp" text="控件2" bg="#00ff00"/>
<text layout_weight="1" text="控件3" bg="#0000ff"/>
</vertical>
);
```
在这个布局中,第三个控件的高度会占满除去控件1和控件2的剩余空间。
# 水平布局: horizontal
水平布局是一种比较简单的布局,会把在它里面的控件按照水平方向依次摆放,如下图所示:
水平布局:
————————————————————————————
| 控件1 | 控件2 | 控件3 | ... |
————————————————————————————
## layout_weight
水平布局中也可以使用layout_weight属性来控制子控件的**宽度**占父布局的比例。和垂直布局中类似,不再赘述。
# 线性布局: linear
实际上,垂直布局和水平布局都属于线性布局。线性布局有一个orientation的属性,用于指定布局的方向,可选的值为`vertical`和`horizontal`。
例如`<linear orientation="vertical"></linear>`相当于`<vertical></vertical>`。
线性布局的默认方向是横向的,因此,一个没有指定orientation属性的线性布局就是横向布局。
# 帧布局: frame
帧布局
# 相对布局: relative
# 勾选框控件: checkbox
# 选择框控件: radio
# 选择框布局: radiogroup
# 开关控件: Switch
开关控件用于表示一个选项是否被选中。
## checked
表示开关是否被选中。可选的值为:
* `true` 打开开关
* `false` 关闭开关
## text
对开关进行描述的文字。
# 进度条控件: progressbar
# 拖动条控件: seekbar
# 下来菜单控件: spinner
# 时间选择控件: timepicker
# 日期选择控件: datepicker
# 浮动按钮控件: fab
# 标题栏控件: toolbar
# 卡片: card
卡片控件是一个拥有圆角、阴影的控件。
## cardBackgroundColor
卡片的背景颜色。
## cardCornerRadius
卡片的圆角半径。
## cardElevation
设置卡片在z轴上的高度,来控制阴影的大小。
## contentPadding
设置卡片的内边距。该属性包括四个值:
* `contentPaddingLeft` 左内边距
* `contentPaddingRight` 右内边距
* `contentPaddingTop` 上内边距
* `contentPaddingBottom` 下内边距
## foreground
使用`foreground="?selectableItemBackground"`属性可以为卡片添加点击效果。
# 抽屉布局: drawer
# 列表: list
# Tab: tab
# ui
## ui.layout(xml)
* `xml` {XML} | {string} 布局XML或者XML字符串
将布局XML渲染为视图(View)对象, 并设置为当前视图。
## ui.layoutFile(xmlFile)
* `xml` {string} 布局XML文件的路径
此函数和`ui.layout`相似,只不过允许传入一个xml文件路径来渲染布局。
## ui.inflate(xml[, parent = null, attachToParent = false])
* `xml` {string} | {XML} 布局XML或者XML字符串
* `parent` {View} 父视图
* `attachToParent` {boolean} 是否渲染的View加到父视图中,默认为false
* 返回 {View}
将布局XML渲染为视图(View)对象。如果该View将作为某个View的子View,我们建议传入`parent`参数,这样在渲染时依赖于父视图的一些布局属性能够正确应用。
此函数用于动态创建、显示View。
```javascript
"ui";
$ui.layout(
<linear id="container">
</linear>
);
// 动态创建3个文本控件,并加到container容器中
// 这里仅为实例,实际上并不推荐这种做法,如果要展示列表,
// 使用list组件;动态创建十几个、几十个View会让界面卡顿
for (let i = 0; i < 3; i++) {
let textView = $ui.inflate(
<text textColor="#000000" textSize="14sp"/>
, $ui.container);
textView.attr("text", "文本控件" + i);
$ui.container.addView(textView);
}
```
# ui.registerWidget(name, widget)
* `name` {string} 组件名称
* `widget` {Function} 组件
注册一个自定义组件。参考示例->界面控件->自定义控件。
# ui.isUiThread()
* 返回 {boolean}
返回当前线程是否是UI线程。
```javascript
"ui";
log($ui.isUiThread()); // => true
$threads.start(function () {
log($ui.isUiThread()); // => false
});
```
## ui.findView(id)
* `id` {string} View的ID
* 返回 {View}
在当前视图中根据ID查找相应的视图对象并返回。如果当前未设置视图或找不到此ID的视图时返回`null`。
一般我们都是通过`ui.xxx`来获取id为xxx的控件,如果xxx是一个ui已经有的属性,就可以通过`$ui.findView()`来获取这个控件。
## ui.finish()
结束当前活动并销毁界面。
## ui.setContentView(view)
* `view` {View}
将视图对象设置为当前视图。
## ui.post(callback[, delay = 0])
* `callback` {Function} 回调函数
* `delay` {number} 延迟,单位毫秒
将`callback`加到UI线程的消息循环中,并延迟delay毫秒后执行(不能准确保证一定在delay毫秒后执行)。
此函数可以用于UI线程中延时执行动作(sleep不能在UI线程中使用),也可以用于子线程中更新UI。
```javascript
"ui";
ui.layout(
<frame>
<text id="result"/>
</frame>
);
ui.result.attr("text", "计算中");
// 在子线程中计算1+ ... + 10000000
threads.start({
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
// 由于不能在子线程操作UI,所以要抛到UI线程执行
ui.post(() => {
ui.result.attr("text", String(sum));
});
});
```
## ui.run(callback)
* `callback` {Function} 回调函数
* 返回 callback的执行结果
将`callback`在UI线程中执行。如果当前已经在UI线程中,则直接执行`callback`;否则将`callback`抛到UI线程中执行(加到UI线程的消息循环的末尾),**并等待callback执行结束(阻塞当前线程)**。
## ui.statusBarColor(color)
* color {string} | {number} 颜色
设置当前界面的状态栏颜色。
```javascript
"ui";
ui.statusBarColor("#000000");
```
## ui.useAndroidResources()
启用使用Android的布局(layout)、绘图(drawable)、动画(anim)、样式(style)等资源的特性。启用该特性后,在project.json中进行以下配置,就可以像写Android原生一样写界面:
```json
{
// ...
androidResources: {
"resDir": "res", // 资源文件夹
"manifest": "AndroidManifest.xml" // AndroidManifest文件路径
}
}
```
res文件夹通常为以下结构:
```
- res
- layout // 布局资源
- drawable // 图片、形状等资源
- menu // 菜单资源
- values // 样式、字符串等资源
// ...
```
可参考示例->复杂界面->Android原生界面。
# 尺寸的单位: Dimension
# Drawables
# 颜色
**(完善中...)**