精华内容
下载资源
问答
  • autojs悬浮窗点击穿透

    2021-06-16 15:04:55
    autojs悬浮窗有两种 FloatyWindow: 可以调整位置, 大小 floaty.rawWindow: 可以设置是否可以触摸 有的人吧, 就想合二为一, 鱼和熊掌都想要, 就研究研究, 也是百度了上百个帖子, 才研究出来, 写个教程费劲哪, 懂的...

    牙叔教程 简单易懂

    使用场景

    想让悬浮窗可以调整大小, 位置, 又想设置悬浮窗是否可触摸

    autojs版本

    8.8.12-0

    悬浮窗简介

    autojs悬浮窗有两种

    • FloatyWindow: 可以调整位置, 大小
    • floaty.rawWindow: 可以设置是否可以触摸

    有的人吧, 就想合二为一, 鱼和熊掌都想要, 就研究研究, 也是百度了上百个帖子, 才研究出来, 写个教程费劲哪,

    懂的东西太少了, 不懂的东西太多了

    代码讲解

    1. 导入类
    importClass(android.view.WindowManager);
    importClass("android.view.Gravity");
    importClass("android.graphics.PixelFormat");
    
    2. 布局
    var w = floaty.window(
      <frame id="parent" gravity="center" bg="#f0f0f0">
        <button id="btn" textSize="30sp">
          牙叔教程 简单易懂
        </button>
      </frame>
    );
    
    3. 设置按钮点击事件, 用于测试触摸功能
    w.btn.click(function () {
      toastLog("牙叔教程 简单易懂");
    });
    
    4. 设置触摸属性
    let parentParent = w.parent.parent.parent.parent;
    setTouchable(parentParent, true);
    
    5. 设置大小等属性
    w.setAdjustEnabled(true);
    w.setSize(600, 600);
    
    setInterval(function () {}, 1000);
    
    6. setTouchable函数
    function setTouchable(view, touchable) {
      let params = view.getLayoutParams();
      if (touchable) {
        params.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
      } else {
        params.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
      }
      log(params.flags);
      windowManager = context.getSystemService(context.WINDOW_SERVICE);
      ui.run(function () {
        windowManager.updateViewLayout(view, params);
      });
    }
    
    7. 控制触摸属性的悬浮窗布局
    // 由于触摸是针对整个悬浮窗的, 所以需要另外的悬浮窗来辅助修改悬浮窗的触摸属性, 
    // 因为一旦悬浮窗设置了不可触摸, 就无法再控制了
    var w2 = floaty.window(
      <frame id="parent" gravity="center" bg="#f0f0f0">
        <button id="btn2" textSize="17sp"></button>
      </frame>
    );
    
    8. 修改触摸属性, 最重要的代码
    let params = parentParent.getLayoutParams();
    if (params.flags == 16777736) {
      log("当前可以触摸, 修改为不可触摸");
      params.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
    } else if (params.flags == 16777752) {
      log("当前不可以触摸, 修改为可触摸");
      params.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
    } else {
      throw new Error("params.flags 未知数: " + params.flags);
    }
    
    windowManager = context.getSystemService(context.WINDOW_SERVICE);
    windowManager.updateViewLayout(parentParent, params);
    

    完整源码

    公众号回复 悬浮窗穿透

    声明

    部分内容来自网络
    本教程仅用于学习, 禁止用于其他用途

    bilibili

    牙叔教程

    微信公众号 牙叔教程

    在这里插入图片描述

    QQ群

    747748653
    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • autojs Auto.js是一个支持无障碍服务的Android平台上的JavaScript IDE,其发展目标是JsBox和Workflow。 这里我打算基于autojs开发一些有意思的脚本。 目前已有 微信朋友圈自动点赞,是增进和微信好友间感情的神器。...
  • * 需要三个悬浮窗一起协作达到Auto.js悬浮窗效果 * win 子菜单悬浮窗 处理子菜单选项点击事件 * win_1 主悬浮按钮 * win_2 悬浮按钮动画替身,只有在手指移动主按钮的时候才会被触发 * 触发时,替身Y值会跟主...

    说明

    本文提供的代码仅供参考。
    可能有些地方在最新版本的Auto.js上面需要做修改,才能运行。

    Auto.js简介

    Auto.js是利用安卓系统的“辅助功能”实现类似于按键精灵一样,可以通过代码模拟一系列界面动作的辅助工作。
    与“按键精灵”不同的是,它的模拟动作并不是简单的使用在界面定坐标点来实现,而是类似与win一般,找窗口句柄来实现的。

    Auto.js使用JavaScript作为脚本语言,目前使用Rhino 1.7.7.2作为脚本引擎,支持ES5与部分ES6特性。

    开发文档

    Auto.js Pro开发文档优化版
    文档尚在完善中,可能有文档描述和代码实际行为有出入的情况。
    模板、样式、generator来自Node.js。

    为什么要使用Auto.js Pro开发脚本,有什么特点?

    吸引我使用Auto.js Pro的原因有很多。最主要的几个原因是:

    • Auto.js Pro能开发免ROOT的安卓脚本
    • Auto.js Pro基于节点操作,能开发全分辨率的脚本,自动适配各种安卓机型
    • Auto.js Pro丰富的UI组件,能自定义各种样式的安卓界面
    • Auto.js Pro使用的javascript的语法比较优雅,代码可读性强
    • Auto.js Pro的命令库非常的丰富,接口比较多
    • Auto.js Pro脚本文件体积比较小。1000行的代码,打包后的apk文件只有3-5M,还没有广告

    相关教程

    Auto.js Pro安卓全分辨率免ROOT引流脚本开发教程

    示例代码

    /**
     * 作者:  大柒
     * 功能:  Auto.js悬浮按钮样例(补间动画)
     * 日期:  2019/04/06
     * 备注:  
     *    补间动画指的是做flash动画时,在两个关键帧中间需要做“补间动画”
     * 才能实现图画的运动;插入补间动画后两个关键帧之间的插补帧是由计算机自动运算而得到的。
     * 也就是说在使用补间动画时,我们开发者指定了动画开始、结束的关键帧
     * 中间的变化是计算机自动帮助我们补齐的。 
     * 
     * 待解决:
     *     (1)悬浮窗初始化的on事件. 没有找到这个方法目前用定时器解决此问题
     *     (2)补间动画结束的on事件. 试了很多都不可行目前用多线程解决此问题
     *     (3)快速双击主按钮会报错
     */
    //此代码由飞云脚本圈整理提供(www.feiyunjs.com)
    
    
    importClass(android.view.WindowManager);
    //activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    importClass(java.lang.Runnable);
    importClass(android.animation.ObjectAnimator)
    importClass(android.animation.PropertyValuesHolder)
    importClass(android.animation.ValueAnimator)
    importClass(android.animation.AnimatorSet)
    importClass(android.view.animation.AccelerateInterpolator)
    importClass(android.view.animation.TranslateAnimation)
    importClass(android.animation.ObjectAnimator)
    importClass(android.animation.TimeInterpolator)
    importClass(android.os.Bundle)
    importClass(android.view.View)
    importClass(android.view.Window)
    
    importClass(android.view.animation.AccelerateDecelerateInterpolator)
    importClass(android.view.animation.AccelerateInterpolator)
    importClass(android.view.animation.AnticipateInterpolator)
    importClass(android.view.animation.AnticipateOvershootInterpolator)
    importClass(android.view.animation.BounceInterpolator)
    importClass(android.view.animation.CycleInterpolator)
    importClass(android.view.animation.DecelerateInterpolator)
    importClass(android.view.animation.LinearInterpolator)
    importClass(android.view.animation.OvershootInterpolator)
    importClass(android.view.animation.PathInterpolator)
    importClass(android.widget.Button)
    importClass(android.widget.ImageView)
    importClass(android.widget.TextView)
    
    var logo_switch = false;//全局: 悬浮窗的开启关闭检测
    var logo_buys = false;//全局: 开启和关闭时占用状态 防止多次点击触发
    var logo_fx = true//全局: 悬浮按钮所在的方向 真左 假右
    var time_0, time_1, time_3//全局: 定时器 点击退出悬浮窗时定时器关闭
    //可修改参数
    var logo_ms = 200//全局:  动画播放时间
    var DHK_ms = 200//全局:  对话框动画播放时间
    var tint_color = "#00000"//全局:  对话框图片颜色
    /**
     * 需要三个悬浮窗一起协作达到Auto.js悬浮窗效果
     * win  子菜单悬浮窗 处理子菜单选项点击事件
     * win_1  主悬浮按钮 
     * win_2  悬浮按钮动画替身,只有在手指移动主按钮的时候才会被触发 
     * 触发时,替身Y值会跟主按钮Y值绑定一起,手指弹起时代替主按钮显示跳动的小球动画
     */
    var win = floaty.rawWindow(
        <frame >//子菜单悬浮窗
            <frame id="id_logo" w="150" h="210" alpha="0"  >
                <frame id="id_0" w="44" h="44" margin="33 0 0 0" alpha="1">
                    <img w="44" h="44" src="#009687" circle="true" />
                    <img w="28" h="28" src="@drawable/ic_perm_identity_black_48dp" tint="#ffffff" gravity="center" layout_gravity="center" />
                    <img id="id_0_click" w="*" h="*" src="#ffffff" circle="true" alpha="0" />
                </frame>
                <frame id="id_1" w="44" h="44" margin="86 28 0 0" alpha="1">
                    <img w="44" h="44" src="#ee534f" circle="true" />
                    <img w="28" h="28" src="@drawable/ic_assignment_black_48dp" tint="#ffffff" gravity="center" layout_gravity="center" />
                    <img id="id_1_click" w="*" h="*" src="#ffffff" circle="true" alpha="0" />
                </frame>
                <frame id="id_2" w="44" h="44" margin="0 83 0 0" alpha="1" gravity="right" layout_gravity="right">
                    <img w="44" h="44" src="#40a5f3" circle="true" />
                    <img w="28" h="28" src="@drawable/ic_play_arrow_black_48dp" tint="#ffffff" margin="8" />
                    <img id="id_2_click" w="*" h="*" src="#ffffff" circle="true" alpha="0" />
                </frame>
                <frame id="id_3" w="44" h="44" margin="86 0 0 28" alpha="1" gravity="bottom" layout_gravity="bottom">
                    <img w="44" h="44" src="#fbd834" circle="true" />
                    <img w="28" h="28" src="@drawable/ic_clear_black_48dp" tint="#ffffff" margin="8" />
                    <img id="id_3_click" w="*" h="*" src="#ffffff" circle="true" alpha="0" />
                </frame>
                <frame id="id_4" w="44" h="44" margin="33 0 0 0" alpha="1" gravity="bottom" layout_gravity="bottom">
                    <img w="44" h="44" src="#bfc1c0" circle="true" />
                    <img w="28" h="28" src="@drawable/ic_settings_black_48dp" tint="#ffffff" margin="8" />
                    <img id="id_4_click" w="*" h="*" src="#ffffff" circle="true" alpha="0" />
                </frame>
            </frame>
            <frame id="logo" w="44" h="44" marginTop="83" alpha="1" />
            <frame id="logo_1" w="44" h="44" margin="0 83 22 0" alpha="1" layout_gravity="right" />
        </frame>
    )
    win.setTouchable(false);//设置子菜单不接收触摸消息
    
    var win_1 = floaty.rawWindow(
        <frame id="logo" w="44" h="44" alpha="0.4" >//悬浮按钮
            <img w="44" h="44" src="#ffffff" circle="true" alpha="0.8" />
            <img id="img_logo" w="32" h="32" src="{{org.autojs.autojs.R.drawable.autojs_material}}" gravity="center" layout_gravity="center" />
            <img id="logo_click" w="*" h="*" src="#ffffff" alpha="0" />
        </frame>
    )
    win_1.setPosition(-30, device.height / 2)//悬浮按钮定位
    
    var win_2 = floaty.rawWindow(
        <frame id="logo" w="{{device.width}}px" h="44" alpha="0" >//悬浮按钮 弹性替身
            <img w="44" h="44" src="#ffffff" circle="true" alpha="0.8" />
            <img id="img_logo" w="32" h="32" src="{{org.autojs.autojs.R.drawable.autojs_material}}" margin="6 6" />
        </frame>
    )
    win_2.setTouchable(false);//设置弹性替身不接收触摸消息
    
    /**
     * 脚本广播事件
     */
    var XY = [], XY1 = [], TT = [], TT1 = [], img_dp = {}, dpZ = 0, logo_right = 0, dpB = 0, dp_H = 0
    events.broadcast.on("定时器关闭", function (X) { clearInterval(X) })
    events.broadcast.on("悬浮开关", function (X) {
        ui.run(function () {
            switch (X) {
                case true:
                    win.id_logo.setVisibility(0)
                    win.setTouchable(true);
                    logo_switch = true
                    break;
                case false:
                    win.id_logo.setVisibility(4)
                    win.setTouchable(false);
                    logo_switch = false
            }
        })
    
    });
    
    events.broadcast.on("悬浮显示", function (X1) {
        ui.run(function () {
            win_2.logo.attr("alpha", "0");
            win_1.logo.attr("alpha", "0.4");
        })
    });
    
    /**
     * 等待悬浮窗初始化
     */
    var terid = setInterval(() => {
        log("13")
        if (TT.length == 0 && win.logo.getY() > 0) {// 不知道界面初始化的事件  只能放到这里将就下了
            ui.run(function () {
                TT = [win.logo.getX(), win.logo.getY()], TT1 = [win.logo_1.getLeft(), win.logo_1.getTop()], anX = [], anY = []// 获取logo 绝对坐标
                XY = [
                    [win.id_0, TT[0] - win.id_0.getX(), TT[1] - win.id_0.getY()],//  获取子菜单 视图和子菜单与logo绝对坐标差值
                    [win.id_1, TT[0] - win.id_1.getX(), TT[1] - win.id_1.getY()],
                    [win.id_2, TT[0] - win.id_2.getX(), 0],
                    [win.id_3, TT[0] - win.id_3.getX(), TT[1] - win.id_3.getY()],
                    [win.id_4, TT[0] - win.id_4.getX(), TT[1] - win.id_4.getY()]]
                log("上下Y值差值:" + XY[0][2] + "DP值:" + (XY[0][2] / 83))
                dpZ = XY[0][2] / 83
                dpB = dpZ * 22
                XY1 = [
                    [parseInt(dpZ * 41), TT1[0] - win.id_0.getLeft(), TT1[1] - win.id_0.getTop()],
                    [parseInt(dpZ * -65), TT1[0] - win.id_1.getLeft(), TT1[1] - win.id_1.getTop()],
                    [parseInt(dpZ * -106), TT1[0] - win.id_2.getLeft(), TT1[1] - win.id_2.getTop()],
                    [parseInt(dpZ * -65), TT1[0] - win.id_3.getLeft(), TT1[1] - win.id_3.getTop()],
                    [parseInt(dpZ * 41), TT1[0] - win.id_4.getLeft(), TT1[1] - win.id_4.getTop()]]
                img_dp.h_b = XY[0][2]//两个悬浮窗Y差值
                img_dp.w = parseInt(dpZ * 9)//计算logo左边隐藏时 X值
                img_dp.ww = parseInt(dpZ * (44 - 9))//计算logo右边隐藏时 X值
                logo_right = win.id_2.getX() - parseInt(dpZ * 22)
                win_1.setPosition(0 - img_dp.w, device.height / 2)
                win.id_logo.setVisibility(4)
                win.id_logo.attr("alpha", "1")
                events.broadcast.emit("定时器关闭", terid)
            })
        }
    }, 100)
    
    time_0 = setInterval(() => {
        //log("11")
    }, 1000)
    
    /**
     * 子菜单点击事件
     */
    function img_down() {
        win_1.logo.attr("alpha", "0.4")
        logo_switch = false
        动画()
    }
    win.id_0_click.on("click", () => {
        toastLog("个人中心")
        img_down()
    })
    
    win.id_1_click.on("click", () => {
        toastLog("日志")
        img_down()
    })
    
    win.id_2_click.on("click", () => {
        toastLog("启动脚本")
        img_down()
    })
    
    win.id_3_click.on("click", () => {
        toastLog("结束脚本")
        img_down()
    })
    
    win.id_4_click.on("click", () => {
        设置();
        img_down();
    })
    var win_sj, Pack = "", Acti = "", XC_SJ, logo_switch_1 = true
    
    function 设置() {
        XC_SJ = threads.start(function () {
            logo_switch_1 = true
            if (auto.service != null) {
                Pack = currentPackage()
                Acti = currentActivity()
            } else {
                try {
                    Pack = currentPackage()
                    Acti = currentActivity()
                } catch (error) {
                    Pack = "未知"
                    Acti = "未知"
                }
            }
            win_sj = floaty.rawWindow(
                <frame w="{{device.width}}px" h="{{device.height}}px" >//模拟对话框_设置
                    <frame id="off" bg="#000000" alpha="0" />
                    <frame id="主控件" w="{{device.width-160}}px" h="auto" alpha="0" layout_gravity="center" >
                        <card w="*" h="*" cardCornerRadius="15dp" cardBackgroundColor="#ffffff"
                            cardElevation="30dp" foreground="?selectableItemBackground">
                            <vertical w="*" h="auto">
                                <text margin="20 20 20 0" text="设置" textSize="24sp" textStyle="bold" textColor="#000000" />
                                <scroll w="*" h="auto" marginBottom="10">
                                    <vertical w="*" h="auto">
                                        <frame w="*" >
                                            <frame marginLeft="20" w="auto">
                                                <img gravity="center|center_vertical" layout_gravity="center" w="26" h="26" src="@drawable/ic_accessible_black_48dp" />
                                            </frame>
                                            <button id="打开无障碍" text="打开无障碍服务" paddingLeft="60" gravity="left|center_vertical" layout_gravity="center" w="*" h="60" style="Widget.AppCompat.Button.Borderless" textColor="#000000" textSize="16sp" typeface="normal" />
                                        </frame>
                                        <frame w="*">
                                            <frame marginLeft="20" w="auto">
                                                <img gravity="center|center_vertical" layout_gravity="center" w="26" h="26" src="@drawable/ic_adb_black_48dp" tint="#000000" />
                                            </frame>
                                            <button id="当前包名" text="当前应用包名:{{Pack}}" paddingLeft="60" gravity="left|center_vertical" layout_gravity="center" w="*" h="auto" style="Widget.AppCompat.Button.Borderless" textColor="#000000" textSize="15sp" typeface="normal" ellipsize="marquee" />
                                        </frame>
                                        <frame w="*">
                                            <frame marginLeft="20" w="auto">
                                                <img gravity="center|center_vertical" layout_gravity="center" w="26" h="26" src="@drawable/ic_blur_on_black_48dp" tint="#000000" />
                                            </frame>
                                            <button id="当前活动" text="当前活动:{{Acti}}" paddingLeft="60" gravity="left|center_vertical" layout_gravity="center" w="*" h="auto" style="Widget.AppCompat.Button.Borderless" textColor="#000000" textSize="15sp" typeface="normal" ellipsize="marquee" />
                                        </frame>
                                        <frame w="*">
                                            <frame marginLeft="20" w="auto">
                                                <img gravity="center|center_vertical" layout_gravity="center" w="26" h="26" src="@drawable/ic_home_black_48dp" tint="#000000" />
                                            </frame>
                                            <button id="打开主页面" text="打开主页面" paddingLeft="60" gravity="left|center_vertical" layout_gravity="center" w="*" h="60" style="Widget.AppCompat.Button.Borderless" textColor="#000000" textSize="16sp" typeface="normal" />
                                        </frame>
                                        <frame w="*">
                                            <frame marginLeft="20" w="auto">
                                                <img gravity="center|center_vertical" layout_gravity="center" w="26" h="26" src="@drawable/ic_touch_app_black_48dp" tint="#000000" />
                                            </frame>
                                            <button id="指针位置" text="指针位置[Root]" paddingLeft="60" gravity="left|center_vertical" layout_gravity="center" w="*" h="60" style="Widget.AppCompat.Button.Borderless" textColor="#000000" textSize="16sp" typeface="normal" />
                                        </frame>
                                        <frame w="*">
                                            <frame marginLeft="20" w="auto">
                                                <img gravity="center|center_vertical" layout_gravity="center" w="26" h="26" src="@drawable/ic_exit_to_app_black_48dp" tint="#000000" />
                                            </frame>
                                            <button id="关闭" text="退出悬浮窗:" paddingLeft="60" gravity="left|center_vertical" layout_gravity="center" w="*" h="60" style="Widget.AppCompat.Button.Borderless" textColor="#000000" textSize="16sp" typeface="normal" />
                                        </frame>
                                    </vertical>
                                </scroll>
                            </vertical>
                        </card>
                    </frame>
                </frame>
            )
            time_3 = setInterval(() => {
                if (logo_switch_1 && win_sj.主控件.getY() > 0) {
                    logo_switch_1 = false
                    对话框动画(true, win_sj.off, win_sj.主控件)
                    events.broadcast.emit("定时器关闭", time_3)
                }
                // log("设置0")
            }, 100)
    
            win_sj.打开无障碍.on("click", () => {
                win_sj_off(false)
                app.startActivity({
                    action: "android.settings.ACCESSIBILITY_SETTINGS"
                });
            })
            win_sj.当前包名.on("click", () => {
                win_sj_fz1(Pack)
            })
            win_sj.当前活动.on("click", () => {
                win_sj_fz1(Acti)
            })
            win_sj.打开主页面.on("click", () => {
                win_sj_off(false)
                app.startActivity({
                    action: "android.intent.action.VIEW", //此处可为其他值
                    packageName: "org.autojs.autojs",
                    className: "org.autojs.autojs.ui.splash.SplashActivity"
                    //此处可以加入其他内容,如data、extras
                });
            })
            win_sj.指针位置.on("click", () => {
                toastLog("作者不会\n需要的自己设置意图")
                win_sj_off(false)
            })
            win_sj.关闭.on("click", () => {
                //定时器关闭
                win_sj_off(true)
            })
            win_sj.off.on("click", () => {
                win_sj_off(false)
            })
            function win_sj_fz1(X) {
                if (X == "未知") {
                    toastLog("无障碍服务未开启")
                } else {
                    toastLog("已复制到剪贴板")
                    setClip(X)
                }
                win_sj_off(false)
            }
            function win_sj_off(E) {
                对话框动画(false, win_sj.off, win_sj.主控件)
                threads.start(function () {
                    sleep(DHK_ms)
                    win_sj.close()
                    clearInterval(time_1)
                    XC_SJ.interrupt()
                    if (E) {
                        win.close()
                        win_1.close()
                        win_2.close()
                        events.broadcast.emit("定时器关闭", time_0)
                        exit()
                    }
                    return
                })
            }
            time_1 = setInterval(() => {
                // log("设置")
            }, 1000)
        })
    }
    
    
    /**
     * 补间动画
     */
    function 动画() {
        var anX = [], anY = [], slX = [], slY = []
        if (logo_switch) {
            if (logo_fx) {
                for (let i = 0; i < XY.length; i++) {
                    anX[i] = ObjectAnimator.ofFloat(XY[i][0], "translationX", parseInt(XY[i][1]), 0);
                    anY[i] = ObjectAnimator.ofFloat(XY[i][0], "translationY", parseInt(XY[i][2]), 0);
                    slX[i] = ObjectAnimator.ofFloat(XY[i][0], "scaleX", 0, 1)
                    slY[i] = ObjectAnimator.ofFloat(XY[i][0], "scaleY", 0, 1)
                }
            } else {
                for (let i = 0; i < XY.length; i++) {
                    anX[i] = ObjectAnimator.ofFloat(XY[i][0], "translationX", XY1[i][1], XY1[i][0]);
                    anY[i] = ObjectAnimator.ofFloat(XY[i][0], "translationY", XY1[i][2], 0);
                    slX[i] = ObjectAnimator.ofFloat(XY[i][0], "scaleX", 0, 1)
                    slY[i] = ObjectAnimator.ofFloat(XY[i][0], "scaleY", 0, 1)
                }
            }
        } else {
            if (logo_fx) {
                for (let i = 0; i < XY.length; i++) {
                    anX[i] = ObjectAnimator.ofFloat(XY[i][0], "translationX", 0, parseInt(XY[i][1]));
                    anY[i] = ObjectAnimator.ofFloat(XY[i][0], "translationY", 0, parseInt(XY[i][2]));
                    slX[i] = ObjectAnimator.ofFloat(XY[i][0], "scaleX", 1, 0)
                    slY[i] = ObjectAnimator.ofFloat(XY[i][0], "scaleY", 1, 0)
                }
            } else {
                for (let i = 0; i < XY.length; i++) {
                    anX[i] = ObjectAnimator.ofFloat(XY[i][0], "translationX", XY1[i][0], XY1[i][1]);
                    anY[i] = ObjectAnimator.ofFloat(XY[i][0], "translationY", 0, XY1[i][2]);
                    slX[i] = ObjectAnimator.ofFloat(XY[i][0], "scaleX", 1, 0)
                    slY[i] = ObjectAnimator.ofFloat(XY[i][0], "scaleY", 1, 0)
                }
            }
        }
        set = new AnimatorSet();
        set.playTogether(
            anX[0], anX[1], anX[2], anX[3], anX[4],
            anY[0], anY[1], anY[2], anY[3], anY[4],
            slX[0], slX[1], slX[2], slX[3], slX[4],
            slY[0], slY[1], slY[2], slY[3], slY[4]);
        set.setDuration(logo_ms);
        threads.start(function () {//动画的结束事件一直没有明白 只能拿线程代替了
            logo_buys = true
            if (logo_switch) {
                //log("开启")
                events.broadcast.emit("悬浮开关", true)
                sleep(logo_ms)
            } else {
                //log("关闭")
                sleep(logo_ms + 100)
                events.broadcast.emit("悬浮开关", false)
            }
            logo_buys = false
        });
        set.start();
    }
    function 对话框动画(X, Y, Z) {//X布尔值 标识显示还是隐藏 Y背景的视图 Z对话框的视图
        var anX = [], anY = [], slX = [], slY = []
        if (X) {
            anX = ObjectAnimator.ofFloat(Z, "translationX", win_1.getX() - (Z.getRight() / 2) + dpB - Z.getLeft(), 0);
            anY = ObjectAnimator.ofFloat(Z, "translationY", win_1.getY() - (Z.getBottom() / 2) + img_dp.h_b - Z.getTop(), 0);
            slX = ObjectAnimator.ofFloat(Z, "scaleX", 0, 1)
            slY = ObjectAnimator.ofFloat(Z, "scaleY", 0, 1)
            animator = ObjectAnimator.ofFloat(Y, "alpha", 0, 0.5)
            animator1 = ObjectAnimator.ofFloat(Z, "alpha", 1, 1)
        } else {
            anX = ObjectAnimator.ofFloat(Z, "translationX", 0, win_1.getX() - (Z.getRight() / 2) + dpB - Z.getLeft());
            anY = ObjectAnimator.ofFloat(Z, "translationY", 0, win_1.getY() - (Z.getBottom() / 2) + img_dp.h_b - Z.getTop());
            slX = ObjectAnimator.ofFloat(Z, "scaleX", 1, 0)
            slY = ObjectAnimator.ofFloat(Z, "scaleY", 1, 0)
            animator = ObjectAnimator.ofFloat(Y, "alpha", 0.5, 0)
            animator1 = ObjectAnimator.ofFloat(Z, "alpha", 1, 0)
        }
        set = new AnimatorSet()
        set.playTogether(
            anX, anY, slX, slY, animator, animator1);
        set.setDuration(DHK_ms);
        set.start();
    }
    
    //记录按键被按下时的触摸坐标
    var x = 0,
        y = 0;
    //记录按键被按下时的悬浮窗位置
    var windowX, windowY; G_Y = 0
    //记录按键被按下的时间以便判断长按等动作
    var downTime; yd = false;
    win_1.logo.setOnTouchListener(function (view, event) {
        if (logo_buys) { return }
        log(event.getAction())
        switch (event.getAction()) {
            case event.ACTION_DOWN:
                x = event.getRawX();
                y = event.getRawY();
                windowX = win_1.getX();
                windowY = win_1.getY();
                downTime = new Date().getTime();
                return true;
            case event.ACTION_MOVE:
                if (logo_switch) { return true; }
                if (!yd) {//如果移动的距离大于h值 则判断为移动 yd为真
                    if (Math.abs(event.getRawY() - y) > 30 || Math.abs(event.getRawX() - x) > 30) { win_1.logo.attr("alpha", "1"); yd = true }
                } else {//移动手指时调整两个悬浮窗位置
                    win_1.setPosition(windowX + (event.getRawX() - x),//悬浮按钮定位
                        windowY + (event.getRawY() - y));
                    win_2.setPosition(0, windowY + (event.getRawY() - y));//弹性 替身定位(隐藏看不到的,松开手指才会出现)
                }
                return true;
            case event.ACTION_UP:                //手指弹起
                //触摸时间小于 200毫秒 并且移动距离小于30 则判断为 点击
                if (logo_buys) { return }//如果在动画正在播放中则退出事件 无操作
                if (Math.abs(event.getRawY() - y) < 30 && Math.abs(event.getRawX() - x) < 30) {
                    //toastLog("点击弹起")
                    if (logo_switch) {
                        logo_switch = false
                        win_1.logo.attr("alpha", "0.4")
                    } else if (logo_fx) {
                        log("左边")
                        win.setPosition(windowX + (event.getRawX() - x),
                            windowY + (event.getRawY() - y) - img_dp.h_b);
                        win.id_logo.setVisibility(0)
                        logo_switch = true
                        win_1.logo.attr("alpha", "0.9")
                    } else {
                        win.setPosition(win_1.getX() + (event.getRawX() - x) - logo_right,
                            win_1.getY() + (event.getRawY() - y) - img_dp.h_b);
                        win.id_logo.setVisibility(0)
                        logo_switch = true
                        win_1.logo.attr("alpha", "0.9")
                    }
                    动画()
                } else if (!logo_switch) {
                    //toastLog("移动弹起")
                    G_Y = windowY + (event.getRawY() - y)
                    win_1.logo.attr("alpha", "0.4")
    
                    if (windowX + (event.getRawX() - x) < device.width / 2) {
                        //toastLog("左边")
                        logo_fx = true
                        animator = ObjectAnimator.ofFloat(win_2.logo, "translationX", windowX + (event.getRawX() - x), 0 - img_dp.w);
                        mTimeInterpolator = new BounceInterpolator();
                        animator.setInterpolator(mTimeInterpolator);
                        animator.setDuration(300);
                        win_2.logo.attr("alpha", "0.4")//动画 替身上场
                        win_1.logo.attr("alpha", "0");//悬浮按钮隐藏
                        win_1.setPosition(0 - img_dp.w, G_Y)//悬浮按钮移动到终点位置等待替身动画结束
                        animator.start();
                    } else {
                        //toastLog("右边")
                        logo_fx = false
                        animator = ObjectAnimator.ofFloat(win_2.logo, "translationX", windowX + (event.getRawX() - x), device.width - img_dp.ww);
                        mTimeInterpolator = new BounceInterpolator();
                        animator.setInterpolator(mTimeInterpolator);
                        animator.setDuration(300);
                        win_2.logo.attr("alpha", "0.4")//动画替身上场
                        win_1.logo.attr("alpha", "0");//悬浮按钮隐藏
                        win_1.setPosition(device.width - img_dp.ww, G_Y)//悬浮按钮移动到终点位置等待替身动画结束
                        animator.start();
                    }
                    threads.start(function () {//动画的结束事件一直没有明白 只能拿线程代替了
                        logo_buys = true
                        sleep(logo_ms + 100)
                        events.broadcast.emit("悬浮显示", 0)
    
                        logo_buys = false
                    });
                }
                yd = false
                return true;
        }
        return true;
    });
    
    
    
    展开全文
  • autojs悬浮窗, 给我待在屏幕里面

    千次阅读 2021-02-18 22:08:18
    文章目录使用场景:原理代码讲解`ACTION_MOVE`超出屏幕的悬浮窗几个坐标的意义关键理解: 预测未来关键代码微信公众号 AutoJsPro教程QQ群 使用场景: 令悬浮窗始终在屏幕之内 原理 在 setOnTouchListener 中, 监听悬浮...

    使用场景:

    令悬浮窗始终在屏幕之内

    原理

    setOnTouchListener 中, 监听悬浮窗坐标,

    如果超出屏幕, 就把悬浮窗坐标设置为屏幕边缘

    代码讲解

    1. 悬浮窗布局

      var window = floaty.rawWindow(
        <frame gravity="center" bg="#ff00ff">
          <button id="action" w="300dp" h="300dp">
            按钮
          </button>
        </frame>
      );
      
    2. 保持悬浮窗不被关闭

      setInterval(() => {}, 1000);
      
    3. 布局完成以后, 获取悬浮窗宽高

      ui.post(function () {
        windowWidth = window.getWidth();
        windowHeight = window.getHeight();
      }, 1000);
      
    4. 触摸监听

      window.action.setOnTouchListener
      

      触摸监听有三种情况:

      1. ACTION_DOWN
      2. ACTION_MOVE
      3. ACTION_UP

      我们主要处理 ACTION_MOVE

    ACTION_MOVE

    1. 坐标系有两个轴: x, y
    2. 悬浮窗在x轴上有以下情形
      1. 悬浮窗x < 0
      2. 0 < 悬浮窗x < 设备宽度
      3. 悬浮窗x > 设备宽度
    3. 悬浮窗在y轴上与x轴情况类似
    4. 所以我们一共有 3 * 3 = 9 种情况

    超出屏幕的悬浮窗

    在这里插入图片描述

    几个坐标的意义

    在这里插入图片描述

    关键理解: 预测未来

    1. 我们判断悬浮窗超出屏幕之外, 是去计算当前的悬浮窗, 如果移动了某段距离,

      那么, 未来这个悬浮窗的某个部分, 就可能超出屏幕之外, 我们就看不见一个完整的悬浮窗了

    2. 我们要计算的是, (当前悬浮窗坐标 + 未来移动的距离) 是否 超出屏幕边缘

    3. 如果未来悬浮窗的坐标超出屏幕边缘, 我们就将悬浮窗置于屏幕边缘

    关键代码

    let xAxisMovingDistance = event.getRawX() - x;
    let yAxisMovingDistance = event.getRawY() - y;
    if (windowX + xAxisMovingDistance < 0) {
      if (windowY + yAxisMovingDistance < 0) {
        window.setPosition(0, 0);
      } else if (windowY + windowHeight + yAxisMovingDistance > device.height) {
        window.setPosition(0, device.height - windowHeight);
      } else {
        window.setPosition(0, windowY + yAxisMovingDistance);
      }
    } else if (windowX + xAxisMovingDistance > device.width - windowWidth) {
      if (windowY + yAxisMovingDistance < 0) {
        window.setPosition(device.width - windowWidth, 0);
      } else if (windowY + windowHeight + yAxisMovingDistance > device.height) {
        window.setPosition(device.width - windowWidth, device.height - windowHeight);
      } else {
        window.setPosition(device.width - windowWidth, windowY + yAxisMovingDistance);
      }
    } else {
      if (windowY + yAxisMovingDistance < 0) {
        window.setPosition(windowX + xAxisMovingDistance, 0);
      } else if (windowY + windowHeight + yAxisMovingDistance > device.height) {
        window.setPosition(windowX + xAxisMovingDistance, device.height - windowHeight);
      } else {
        window.setPosition(windowX + xAxisMovingDistance, windowY + yAxisMovingDistance);
      }
    }
    

    微信公众号 AutoJsPro教程

    在这里插入图片描述

    QQ群

    747748653

    在这里插入图片描述

    展开全文
  • autojs ui及悬浮窗不可用 版本7.0.4 系统Android 11 具体如下图:
  • autojs之开启悬浮窗权限

    千次阅读 2021-07-17 12:45:46
    通过打开当前活动的悬浮窗权限页面,如果权限未打开,则打开悬浮窗权限,然后退出 function 打开悬浮窗权限(){ //打开 当前活动的悬浮窗权限页面 app.startActivity({ packageName: "com.android.settings", ...

    通过打开当前活动的悬浮窗权限页面,如果权限未打开,则打开悬浮窗权限,然后退出

    function 打开悬浮窗权限(){
    
    	//打开 当前活动的悬浮窗权限页面
    	app.startActivity({
    	    packageName: "com.android.settings",
    	    className: "com.android.settings.Settings$AppDrawOverlaySettingsActivity",
    	    data: "package:" + currentPackage()		//当前活动,可以写成固定的
    	});
    	
    	sleep(1000)
    	id("android:id/checkbox").find().forEach(function(t){	//注意是对控件集合操作
    	    if(t.checked()){
    	        toastLog("悬浮窗权限已开启");
    	        back()
    	    }
    	    else{
    	        id("android:id/checkbox").findOne().click()
    	        toastLog("开启悬浮窗权限!");
    	        back()
    	    }
    	});
    
    }
    
    /* 
    	//这种方法是错的!!需要先用find获得控件集合,然后对集合操作
    	if(id("android:id/checkbox").find().checked()){
    	    log(id("android:id/checkbox").checked());
    	}
    	else log("checked") 
    */
    
    展开全文
  • 一种 很简单很笨很低级的 悬浮窗按钮暂停脚本 的方法。
  • /** *完成时间: 2019年3月20日 下午11:24:54 *测试机型: PD1813D *Auto.js版本: 4.1.0 Alpha5 *屏幕: 1080*2280 *备注: 暂无备注 ...var 悬浮控制 = function(window, windowid, ar) { this.Orienta...
  • 由日赚3万网autojs开发交流群整理提供,欢迎大家一起技术交流,学习更多...我们在开发Autojs脚本时,需要使用到悬浮窗功能来控制脚本。那么到底要如何来做呢?今天给大家分享一些,先来看看效果: 附上完整代码: ...
  • * 功能: 悬浮窗单选按钮demo */ var w=floaty.rawWindow( 选项1'> 选项2'> 选项3'> ) w.fbName.setOnCheckedChangeListener( function (radioGroup,id){ var count=radioGroup.getChildCount() var ...
  • 说明 本文提供的代码仅供参考。不建议用于生产环境。 可能有些地方在最新版本的Auto.js上面需要做修改,才能运行。 Auto.js简介 Auto.js是利用安卓系统的“辅助功能”实现类似于按键精灵一样,可以通过代码模拟一...

空空如也

空空如也

1 2 3 4 5 ... 17
收藏数 339
精华内容 135
关键字:

autojs悬浮窗