牙叔教程 简单易懂
\
在上一个教程: autojs自己写布局分析中, 我们绘制了绿框
今天我们要实现的是点击绿框, 弹出点击的节点信息, 就像这样子
思路
手指点击屏幕, 有了一个触摸坐标, 拿触摸坐标和节点的矩形区域作对比, 如果包含该点,
那么就弹出对应节点的信息
设置画板的点击事件
我们在抬起事件中, 获取触摸坐标x,y 传给函数 showDialog
//记录按键被按下时的触摸坐标
var x = 0,
y = 0;
window.canvas.setOnTouchListener(function (view, event) {
switch (event.getAction()) {
case event.ACTION_DOWN:
log("ACTION_DOWN");
break;
case event.ACTION_MOVE:
log("ACTION_MOVE");
break;
case event.ACTION_UP:
log("ACTION_UP");
x = event.getRawX();
y = event.getRawY();
showDialog(x, y);
break;
}
return true;
});
\
判断点是否在矩形区域内
显示对话框之前, 我们要先遍历所有节点, 看点位是否在某个绿框之内
function isPointInRect(point, rect) {
let x = point.x;
let y = point.y;
let x1 = rect.left;
let y1 = rect.top;
let x2 = rect.right;
let y2 = rect.bottom;
if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
return true;
}
return false;
}
\
遍历判断点是否在某个绿框内部
遍历所有的绿框节点
function showDialog(childViewNodes, x, y) {
var len = childViewNodes.length;
// 倒序遍历
for (var i = len - 1; i >= 0; i--) {
let childViewNode = childViewNodes[i];
let bounds = childViewNode.bounds();
let left = bounds.left;
let top = bounds.top;
let right = bounds.right;
let bottom = bounds.bottom;
if (x > left && x < right && y > top && y < bottom) {
log("点击了第" + i + "个元素");
log(childViewNodes[i]);
break;
}
}
}
点击一下, 看看效果
点击了第4个元素
UiObject(id=, sourceNodeId=3826815860980, packageName=org.autojs.autojspro, className=android.view.View, text=null, desc=UI界面.js
28.46 KB
修改于 2022-09-29 17:22:54, indexInParent=0, boundsInParent=[0,0][1440,233], boundsInScreen=[0,669][1440,902], checkable=false, checked=false, focusable=true, focused=false, selected=false, clickable=true, longClickable=true, enabled=true, password=false, scrollable=false)
\
获取要显示的节点信息
autojs的节点有以下条目, 我们封装成模块, 方便调用
// 属性名字
let propertyNames = [
"accessibilityFocused",
"bounds",
"checked",
"className",
"clickable",
"column",
"columnCount",
"columnSpan",
"columnSpan",
"depth",
"desc",
"dismissable",
"drawingOrder",
"editable",
"enabled",
"focusable",
"fullId",
"id",
"idHex",
"indexInParent",
"longClickable",
"packageName",
"row",
"rowCount",
"rowSpan",
"scrollable",
"selected",
"text",
"visibleToUser",
];
module.exports = propertyNames;
节点中的这些属性对应的值, 有的是方法, 有的是布尔值,
因此我们还要判断一下值的类型, 如果是函数, 那么就执行函数, 否则直接赋值即可
判断变量类型
function getVariableType(variable) {
return Object.prototype.toString.call(variable);
}
判断变量是不是函数
function isFunctionType(variable) {
let variableType = getVariableType(variable);
if (variableType === "[object Function]") {
return true;
} else {
return false;
}
}
获取节点信息
function getViewNodeInfoDialog(viewNode) {
var len = propertyNames.length;
let arr=[]
for (var i = 0; i < len; i++) {
var propertyName = propertyNames[i];
let value = viewNode[propertyName];
if (isFunctionType(value)) {
value = value();
}
if (getVariableType(value) === "[object Null]" || getVariableType(value) === "[object Undefined]") {
value = "";
}
arr.push({
name: propertyName,
value: value
})
}
return arr;
}
打印看看
[ { name: 'accessibilityFocused', value: false },
{ name: 'bounds', value: Rect(0, 669 - 1440, 902) },
{ name: 'checked', value: false },
{ name: 'className', value: 'android.view.View' },
{ name: 'clickable', value: true },
{ name: 'column', value: -1 },
{ name: 'columnCount', value: 0 },
{ name: 'columnSpan', value: -1 },
{ name: 'columnSpan', value: -1 },
{ name: 'depth', value: 13 },
{ name: 'desc',
value: 'UI界面.js\n28.46 KB\n修改于 2022-09-29 17:22:54' },
{ name: 'dismissable', value: false },
{ name: 'drawingOrder', value: 0 },
{ name: 'editable', value: false },
{ name: 'enabled', value: true },
{ name: 'focusable', value: true },
{ name: 'fullId', value: '' },
{ name: 'id', value: '' },
{ name: 'idHex', value: '' },
{ name: 'indexInParent', value: 0 },
{ name: 'longClickable', value: true },
{ name: 'packageName', value: 'org.autojs.autojspro' },
{ name: 'row', value: -1 },
{ name: 'rowCount', value: 0 },
{ name: 'rowSpan', value: -1 },
{ name: 'scrollable', value: false },
{ name: 'selected', value: false },
{ name: 'text', value: '' },
{ name: 'visibleToUser', value: true } ]
信息显示到对话框
对话框的基本样式
importClass(android.graphics.drawable.GradientDrawable);
let view = ui.inflate(<text>牙叔教程</text>, null, false);
let dialog = dialogs.build({
customView: view,
});
let dialogWindow = dialog.getWindow();
setBackgroundRoundRounded(dialogWindow);
dialog.show();
function setBackgroundRoundRounded(view) {
let gradientDrawable = new GradientDrawable();
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
gradientDrawable.setColor(colors.parseColor("#c8e6c9"));
gradientDrawable.setCornerRadius(60);
view.setBackgroundDrawable(gradientDrawable);
}
\
autojs的对话框分析
有以下几个特点:
- 圆角
- 可以滚动
- 有分割线
- 有确定按钮
布局
<vertical padding="8">
<list id="list" layout_weight="1">
...
</list>
<text>
确定
</text>
</vertical>,
listView我们需要修改一下字体大小和颜色
function createAdapter(adapter, textSize, textColor) {
let result = new JavaAdapter(RecyclerView.Adapter, {
onCreateViewHolder: function (parent, viewType) {
return adapter.onCreateViewHolder(parent, viewType);
},
onBindViewHolder: function (vh, i) {
adapter.onBindViewHolder(vh, i);
vh.itemView.name.setTextSize(textSize);
vh.itemView.name.setTextColor(colors.parseColor(textColor));
vh.itemView.value.setTextSize(textSize);
vh.itemView.value.setTextColor(colors.parseColor(textColor));
},
getItemCount: function () {
return adapter.getItemCount();
},
});
return result;
}
let adapter = createAdapter(recyclerView.getAdapter(), textSize, textColor);
recyclerView.setAdapter(adapter);
界面效果如下
到这里对话框就做完了, 有时间的话继续写布局分析的其他功能
环境
设备: 小米11pro
Android版本: 12
雷电模拟器:9.0.17
Android版本: 9
Autojs版本: 9.2.13
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途