文章目录

  • 模拟滚动的实现方式
  • 具体实现
  • 如何使用

模拟滚动的实现方式

Android 提供了集中实现模拟滚动的方式:

  • InstrumentationsendPointerSync()
  • InputManagerinjectInputEvent()
  • AccessibilityServicedispatchGesture()方法

这篇文章主要是介绍如何利用InputManager来实现模拟滚动,先看一下效果图:

具体实现

由于injectInputEvent@hide的,所以需要使用反射调用此方法。

    public class SwipeEvent {                /**         * @param fromX 起始x坐标         * @param fromY 起始y坐标         * @param toX 结束x坐标         * @param toY 结束y坐标         * @param step 单次滑动长度         */        public void makeSwipeDown(int fromX, int fromY, int toX, int toY, int step) {            InputManager inputManager = (InputManager) getSystemService(Context.INPUT_SERVICE);            int y = fromY;            long downTime = SystemClock.uptimeMillis();            long eventTime = SystemClock.uptimeMillis();            // 模拟down            MotionEvent motionEvent = null;            motionEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, fromX, fromY, 0);            // 将MotionEvent的输入源设置为InputDevice.SOURCE_TOUCHSCREEN,输入源为触摸屏幕            motionEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);            // mode为1,INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT            invokeInjectInputEventMethod(inputManager, motionEvent, 1);            // 模拟move            int stepCount = (fromY - toY) / step;            for (int i = 0; i < stepCount; i++) {                y -= step;                motionEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, fromX, y, 0);                motionEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);                // mode为2,INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH                invokeInjectInputEventMethod(inputManager, motionEvent, 2);                Log.i("cwx", "y:" + y);            }            // 模拟up            if (y <= toY) {                motionEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, toX, y, 0);                motionEvent.setSource(InputDevice.SOURCE_TOUCHSCREEN);                invokeInjectInputEventMethod(inputManager, motionEvent, 2);            }        }        private void invokeInjectInputEventMethod(InputManager inputManager, InputEvent event, int mode) {            Class<?> clazz = null;            Method injectInputEventMethod = null;            Method recycleMethod = null;            try {                clazz = Class.forName("android.hardware.input.InputManager");            } catch (ClassNotFoundException e) {                e.printStackTrace();            }            try {                injectInputEventMethod = clazz.getMethod("injectInputEvent", InputEvent.class, int.class);            } catch (NoSuchMethodException e) {                e.printStackTrace();            }            try {                injectInputEventMethod.invoke(inputManager, event, mode);                // 准备回收event的方法                recycleMethod = event.getClass().getMethod("recycle");                //执行event的recycle方法                recycleMethod.invoke(event);            } catch (IllegalAccessException e) {                e.printStackTrace();            } catch (InvocationTargetException e) {                e.printStackTrace();            } catch (NoSuchMethodException e) {                e.printStackTrace();            }        }    }

上面涉及到参数inputSource,在InputManagerinjectInputEvent中代表的是mode,而InputManager也提供了三种mode,下面介绍一下:

    /**     * Input Event Injection Synchronization Mode: None.     * Never blocks.  Injection is asynchronous and is assumed always to be successful.     * 永远不停止,注入输入时异步的,并假设总是成功的。     * @hide     */    public static final int INJECT_INPUT_EVENT_MODE_ASYNC = 0; // see InputDispatcher.h    /**     * Input Event Injection Synchronization Mode: Wait for result.     * Waits for previous events to be dispatched so that the input dispatcher can     * determine whether input event injection will be permitted based on the current     * input focus.  Does not wait for the input event to finish being handled     * by the application.     * 等待调度之前的事件,以便调度程序可以根据当前的输入焦点确定是否允许输入事件注入,不必等待程序处理完输入事件。     * @hide     */    public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_RESULT = 1;  // see InputDispatcher.h    /**     * Input Event Injection Synchronization Mode: Wait for finish.     * Waits for the event to be delivered to the application and handled.     * 等待事件传递到应用程序并进行处理     * @hide     */    public static final int INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH = 2;  // see InputDispatcher.h

如何使用

在由于是模拟滚动,当然比较耗时,我将它放进子线程中执行。

final SwipeEvent swipeEvent = new SwipeEvent();new Thread(new Runnable() {    @Override    public void run() {        swipeEvent.makeSwipeDown(0, 1800, 0, 400, 50);    }}).start();

更多相关文章

  1. Ubuntu下查找.android/avd
  2. 编译android的linux内核
  3. 第17天android:《android从零开始》视频(1-5)
  4. Android(安卓)EditView
  5. Android(安卓)4.0.1 源码下载,编译和运行
  6. scrollview 滚动条
  7. Android(安卓)模拟新浪微博-随便看看栏目
  8. Android上的模拟点击
  9. Android下模拟按键输入

随机推荐

  1. Android事件的分发、拦截和执行
  2. android_Server_Socket_通信序列化实现
  3. Android(安卓)高德地图 Polyline 设置点
  4. android- activity,Application,activity
  5. Error generating final archive
  6. android(bug) USB BUG
  7. android代码分析,及Terminal使用
  8. Android(安卓)使用USB与PC通信之ADB方式
  9. Android(安卓)自定义圆形进度条 带刻度进
  10. Android Root刷机资源 & Google Nexus资