我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第8篇文章,点击查看活动详情
牙叔教程 简单易懂
效果
思路
灵动岛就是一个悬浮窗, 我们不做具体的功能, 只做表面工作,
所以我们只写一个悬浮窗;
悬浮窗不能干扰用户操作, 因此, 在绘制球的时候, 要用另一个悬浮窗,
该悬浮窗不响应任何点击事件, 只管绘制
所以一共有两个悬浮窗;
- 通知栏一个
- 全屏一个
灵动岛悬浮窗
xml代码
this.window = floaty.rawWindow(
<card id="root" cardCornerRadius="{{cardCornerRadius}}px" gravity="center" w="{{ windowWidth }}px" h="{{ windowHeight }}px" cardBackgroundColor="#000000">
<text id="count" w="*" gravity="center" textColor="#ff000f" textSize="{{textSize}}px">
0
</text>
</card>
);
为了在各中分辨率都有看上去一致的体验, 依然是先计算宽高, 再显示UI
this.config = {
width: {
ratio: 0.2,
},
height: {
ratio: 1,
},
};
this.config.width = parseInt(device.width * this.config.width.ratio);
this.config.height = parseInt(STATUS_BAR_HEIGHT * this.config.height.ratio);
为了在UI线程中获取到变量的值, 需要绑定一下变量
runtime.ui.bindingContext.windowWidth = windowWidth;
如果太长记不住, 可以在vscode添加代码片段
"runtime.ui.bindingContext.windowWidth=windowWidth": {
"scope": "javascript,typescript",
"prefix": "bindui",
"body": ["runtime.ui.bindingContext.windowWidth=windowWidth;"],
"description": "runtime.ui.bindingContext.windowWidth=windowWidth"
},
输入的之后, 输入 bindui, 就可以以快速输入这行代码
runtime.ui.bindingContext.windowWidth = windowWidth;
悬浮窗可以任意移动, 使用的是上一个教程封装的代码
makeWindowMoveable
上一个教程是: autojs悬浮窗翻译单词
灵动岛画完了, 我们画灵动球
灵动球
点击灵动岛, 灵动球就出现了, 灵动球绘制在一个全屏的悬浮窗
全屏悬浮窗
这个是之前的全屏方法
function fullScreen(window) {
let LayoutParams = android.view.WindowManager.LayoutParams;
let mWindow = getClassField(window, "mWindow");
log(mWindow); // com.stardust.autojs.core.floaty.RawWindow@26b1509
let params = mWindow.getWindowLayoutParams();
//设置全屏悬浮窗
params.flags |= LayoutParams.FLAG_FULLSCREEN | LayoutParams.FLAG_LAYOUT_IN_SCREEN | LayoutParams.FLAG_LAYOUT_NO_LIMITS;
ui.run(function () {
mWindow.updateWindowLayoutParams(params);
window.setSize(device.width, device.height);
});
}
现在的全屏
window.setSize(-1, -1);
\
灵动球慢慢出现
点一下灵动岛, 灵动球慢慢出现
画球就是用canvas的drawCircle
canvas.drawCircle(ballData.centerX, ballData.centerY, ballData.radius, this.paint);
小球向下运动, 我们可以用 ValueAnimator 设置监听, 来改变球心的高度
this.valueAnimator = ValueAnimator.ofFloat(beginValue, endValue);
this.valueAnimator.setDuration(1000);
this.valueAnimator.addUpdateListener({
onAnimationUpdate: function (animation) {
let value = animation.getAnimatedValue();
ballData.centerY = value;
},
});
加一条线
canvas.drawLine(islandWindowRect.centerX, islandWindowRect.centerY, ballData.centerX, ballData.centerY, this.paint);
\
点哪儿球去哪里
这里我们新增加了两个ValueAnimator, 用来控制小球运动中的XY;
this.valueAnimatorX = ValueAnimator.ofFloat(beginValueX, endValueX, beginValueX);
this.valueAnimatorY = ValueAnimator.ofFloat(beginValueY, endValueY, beginValueY);
动画要同时执行
this.animatorSet = new AnimatorSet();
this.animatorSet.playTogether(this.valueAnimatorX, this.valueAnimatorY);
this.animatorSet.setDuration(300);
在手指按下弹起后, 触发该动画
switch (event.getAction()) {
case event.ACTION_DOWN:
return true;
case event.ACTION_MOVE:
return true;
case event.ACTION_UP:
let touchPoint = {
x: event.getRawX(),
y: event.getRawY(),
};
that.updateTouchValueAnimator(touchPoint);
that.animatorSet.start();
return true;
}
\
屏幕碎裂效果
用ps搞一张玻璃破碎的图片, 或者多搞几张随机选择绘制图片
for (var i = 0; i < len; i++) {
let glass = this.glasses[i];
canvas.drawBitmap(this.glassBitmap, glass.x - this.glassBitmapHalfWidth, glass.y - this.glassBitmapHalfHeight, this.paint);
}
文字教程, 听不到声音, 我就不加音效了
环境
设备: 小米11pro
Android版本: 12
雷电模拟器:9.0.17
Android版本: 9
Autojs版本: 9.2.13
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途