牙叔教程 简单易懂
使用场景
自定义控件
效果展示
autojs版本
8.8.20-0
为什么自定义控件
为了UI界面漂亮
怎样自定义控件
autojs软件自带的示例 / 界面控件 / 自定义控件 , 这是简单的例子, 可以看看
商店里面也有一些自定义控件例子,
比如
自定义控件Switch(这是大柒写的, 跟我写的自定义不一样),
MagicIndicator(这是沐泠写的)
Shape3.0
ShimmerButton
自定义控件
等等
自定义控件思路
一般我们是为了修改控件的颜色, 形状, 布局, 以及运动效果,
对应的修改思路如下:
颜色: 修改控件背景, 前景, 其中使用频率最高的是view.setBackgroundDrawable
形状: 使用canvas画形状
布局: CustomView.prototype.render
运动效果: animation
自定义控件难点
主要是距离的计算
必须搞清楚 margin, padding, view.getMeasuredHeight();
getLeft(), getWidth(), getX(), getPaddingLeft(), rect, drawRoundRect
他们之间的关系;
尤其是涉及到了文字, 文字居中更难,必须了解 getFontMetricsInt()
本教程的自定义Switch可以定义的属性
文字颜色
文字大小
轨道宽高
轨道颜色
轨道圆角
进度条颜色
小球圆角
小球颜色
小球点击事件
代码讲解
1. 停止其他脚本, 主要方便测, 不然脚本运行的多了, 容易报错
engines.all().map((ScriptEngine) => {
if (engines.myEngine().toString() !== ScriptEngine.toString()) {
ScriptEngine.forceStop();
}
});
2. 导入用到的类
importClass(android.graphics.PaintFlagsDrawFilter);
importClass(android.graphics.Color);
importClass(android.animation.ObjectAnimator);
importClass(android.animation.AnimatorListenerAdapter);
importClass(android.util.TypedValue);
3. UI界面
ui.layout(
<vertical gravity="center">
<text textSize="30sp" text="牙叔教程" textStyle="bold" w="*" gravity="center"></text>
<custom-view
id="customView"
textColor="#5e35b1"
trackColor="#0091ea"
progressBarColor="#ffeb3b"
ballColor="#ff8a65"
w="200dp"
h="80dp"
textSize="30sp"
trackRadius="60"
ballRadius="60"
></custom-view>
<custom-view
...
></custom-view>
<custom-view
...
></custom-view>
</vertical>
);
自定义控件主要代码
1. 所有单位统一转换为px
const displayMetrics = context.getResources().getDisplayMetrics();
const all_2Px = (value) => {
if (value.indexOf("px") >= 0) {
let result = value.replace("px", "");
return parseInt(result);
} else if (value.indexOf("dp") >= 0) {
let result = parseFloat(value.replace("dp", ""));
result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, result, displayMetrics);
return parseInt(result);
} else if (value.indexOf("in") >= 0) {
let result = parseFloat(value.replace("in", ""));
result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_IN, result, displayMetrics);
return parseInt(result);
} else if (value.indexOf("mm") >= 0) {
let result = parseFloat(value.replace("mm", ""));
result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, result, displayMetrics);
return parseInt(result);
} else if (value.indexOf("pt") >= 0) {
let result = parseFloat(value.replace("pt", ""));
result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PT, result, displayMetrics);
return parseInt(result);
} else if (value.indexOf("sp") >= 0) {
let result = parseFloat(value.replace("sp", ""));
result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, result, displayMetrics);
return parseInt(result);
} else {
return parseInt(value);
}
};
2. render
CustomView.prototype.render = function () {
return (
<LinearLayout margin="6 6 6 6" padding="2 2 2 2" h="60dp" w="300dp" gravity="center_vertical">
<card id="ball" w="53dp" h="53dp" cardCornerRadius="25dp" cardElevation="3dp">
<View layout_width="match_parent" layout_height="match_parent"></View>
</card>
</LinearLayout>
);
};
3. 注册自定义控件
ui.registerWidget("custom-view", CustomView);
4. 定义各种属性
this.defineAttr("textColor", (view, attr, value, defineSetter) => {
textColor = colors.parseColor(value);
});
this.defineAttr("w", (view, attr, value, defineSetter) => {
view.attr("w", value);
});
this.defineAttr("h", (view, attr, value, defineSetter) => {
view.attr("h", value);
});
this.defineAttr("trackRadius", (view, attr, value, defineSetter) => {
trackRadius = all_2Px(value);
});
this.defineAttr("ballRadius", (view, attr, value, defineSetter) => {
ballRadius = all_2Px(value);
});
this.defineAttr("textSize", (view, attr, value, defineSetter) => {
textSize = all_2Px(value);
});
this.defineAttr("trackColor", (view, attr, value, defineSetter) => {
trackColor = colors.parseColor(value);
});
this.defineAttr("progressBarColor", (view, attr, value, defineSetter) => {
progressBarColor = colors.parseColor(value);
});
this.defineAttr("ballColor", (view, attr, value, defineSetter) => {
ballColor = colors.parseColor(value);
view.getChildAt(0).getChildAt(0).setBackgroundColor(ballColor);
});
```
5. 定义点击事件对应的动画
view.ball.on("click", () => {
log("click");
moveBall(view.ball);
view.widget.clickAction();
});
6. 定义动画监听
animator.addUpdateListener(
new android.animation.ValueAnimator.AnimatorUpdateListener({
onAnimationUpdate: function (valueAnimator) {
drawProgressBar(ballView.getParent(), valueAnimator, ball);
},
})
);
声明
部分内容来自网络
本教程仅用于学习, 禁止用于其他用途
bilibili
微信公众号 牙叔教程
QQ群
747748653