模拟器上下键模拟滑动

需求:Android模拟器点击上下键,app上下滑动
实现:

  1. 重写onKeyDown方法
  2. 创建MotionEvent事件
  3. 分发MotionEvent(dispatchTouchEvent)

onKeyDown的重写
在Activity中,重写onKeyDown方法

  public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            moveTaskToBack(false);
            return true;
        } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {//按向上键
            Log.e("KeyUp", "" + event.getSource());
            TouchUtil.setMoveToTop(400, this);
            return true;
        }else if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {//按向下键
            Log.e("KeyDown", "" + event.getSource());
            TouchUtil.setMoveToBottom(400, this);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

创建MotionEvent事件
通过MotionEvent.obtain()方法创建我们所需要的事件,

MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_DOWN, x, y, 0)
MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_MOVE, x, y, 0)
MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_UP, x, y, 0));

分别创建了ACTION_DOWN,ACTION_MOVE,ACTION_UP三个事件,X,Y为当前事件的坐标,SystemClock.uptimeMillis() 为 从开机到现在的毫秒数(手机睡眠的时间不包括在内),最后一个参数metaState,翻译为:生成事件时生效的任何元/修饰键的状态。 native方法中的参数,我们传0(未知)

/**
     * Create a new MotionEvent, filling in a subset of the basic motion
     * values.  Those not specified here are: device id (always 0), pressure
     * and size (always 1), x and y precision (always 1), and edgeFlags (always 0).
     *
     * @param downTime The time (in ms) when the user originally pressed down to start
     * a stream of position events.  This must be obtained from {@link SystemClock#uptimeMillis()}.
     * @param eventTime  The the time (in ms) when this specific event was generated.  This
     * must be obtained from {@link SystemClock#uptimeMillis()}.
     * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
     * @param x The X coordinate of this event.
     * @param y The Y coordinate of this event.
     * @param metaState The state of any meta / modifier keys that were in effect when
     * the event was generated.
     */
    static public MotionEvent obtain(long downTime, long eventTime, int action,
            float x, float y, int metaState) {
        return obtain(downTime, eventTime, action, x, y, 1.0f, 1.0f,
                metaState, 1.0f, 1.0f, 0, 0);
    }

分发MotionEvent
用dispatchTouchEvent来分发上一部创建的MotionEvent

   dispatchTouchEvent(MotionEvent ev)

完整代码如下

public class TouchUtil {
    private static  final  String TAG ="TouchUtil";
    private static View view;
    private static float x;
    private static float y;

    /**
         * 模仿手指点击控件事件
         * @param view  控件
         * @param x     相对控件的X坐标
         * @param y     相对控件的Y坐标
         */
        private static void simulateClick(View view, float x, float y) {
            TouchUtil.view = view;
            TouchUtil.x = x;
            TouchUtil.y = y;
            long downTime = SystemClock.uptimeMillis();
            final MotionEvent downEvent = MotionEvent.obtain(downTime, downTime,MotionEvent.ACTION_DOWN, x, y, 0);
            downTime += 1000;
            final MotionEvent upEvent = MotionEvent.obtain(downTime, downTime,MotionEvent.ACTION_UP, x, y, 0);
            view.onTouchEvent(downEvent);
            view.onTouchEvent(upEvent);
            downEvent.recycle();
            upEvent.recycle();
        }

        /**
         * 模仿手机点击屏幕事件
         * @param x X坐标
         * @param y Y坐标
         * @param activity 传进去的活动对象
         */
        public static void setFingerClick(int x, int y, Activity activity){
            MotionEvent evenDownt = MotionEvent.obtain(System.currentTimeMillis(),
                    System.currentTimeMillis() + 100, MotionEvent.ACTION_DOWN, x, y, 0);
            activity.dispatchTouchEvent(evenDownt);
            MotionEvent eventUp = MotionEvent.obtain(System.currentTimeMillis(),
                    System.currentTimeMillis() + 100, MotionEvent.ACTION_UP, x, y, 0);
            activity.dispatchTouchEvent(eventUp);
            evenDownt.recycle();
            eventUp.recycle();
            Log.d(TAG, "setFingerClick: ");
        }

        /**
         * 模拟向下滑动事件
         * @param distance 滑动的距离
         * @param activity 传进去的活动对象
         */
        public static void setMoveToBottom(int distance,Activity activity){
            activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_DOWN, 400, 500, 0));
            activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_MOVE, 400, 500-distance/2, 0));
            activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_MOVE, 400, 500-distance, 0));
            activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_UP, 400, 500-distance, 0));
            Log.d(TAG, "setMoveToBottom: ");
        }

        /**
         * 模拟向上滑动事件
         * @param distance 滑动的距离
         * @param activity 传进去的活动对象
         */
        public static void setMoveToTop(int distance,Activity activity){
            activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_DOWN, 400, 500, 0));
            activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_MOVE, 400, 500+distance/2, 0));
            activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_MOVE, 400, 500+distance, 0));
            activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_UP, 400, 500+distance, 0));
            Log.d(TAG, "setMoveToTop: ");
        }

}

在Activity中调用第一步onKeyDown的重写,可以实现模拟器上下点击,app对应滑动的效果。

如果注释掉这句

activity.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(),
                    MotionEvent.ACTION_MOVE, 400, 500-distance/2, 0));

表现为快速滑动,滑动距离大,否则表现为拖动,滑动距离少

参考博客:

模拟手指点击滑动事件
android之DPAD上下左右四个键控制
Android手势处理及模拟滑动事件
Android 模拟触摸动作MotionEvent事件
android 处理鼠标滚轮事件
Android中实现滑动效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值