如何在安卓系统中通过编程触发触摸事件?

61

我想要触发一个如下所示的触摸事件:

首先手指在屏幕的(0,50%)处按下并滑动到屏幕的(50%,50%)处,然后离开(将手指移开屏幕)

我已经找到一些类似这样的东西:

MotionEvent event = MotionEvent.obtain(downTime, eventTime, action, x, y, pressure, size, metaState, xPrecision, yPrecision, deviceId, edgeFlags);

onTouchEvent(event);

然而,如何模拟上述情况?我需要创建2个事件吗?例如onTouchDown、onMove等等...感谢您的帮助。


你可以覆盖 http://developer.android.com/reference/android/view/View.OnTouchListener.html - QuokMoon
现在我已经有了ontouchEvent函数,我想以编程的方式触发它,而不是用户手动触摸屏幕。 - user782104
我考虑过直接在函数中调用ontouch事件,但这样比较复杂,所以我认为最好的方法是模拟触摸事件。 - user782104
4个回答

114
// Obtain MotionEvent object
long downTime = SystemClock.uptimeMillis();
long eventTime = SystemClock.uptimeMillis() + 100;
float x = 0.0f;
float y = 0.0f;
// List of meta states found here:     developer.android.com/reference/android/view/KeyEvent.html#getMetaState()
int metaState = 0;
MotionEvent motionEvent = MotionEvent.obtain(
    downTime, 
    eventTime, 
    MotionEvent.ACTION_UP, 
    x, 
    y, 
    metaState
);

// Dispatch touch event to view
view.dispatchTouchEvent(motionEvent);

4
我该如何声明和初始化视图对象? - TheLogicGuy
5
左滑、右滑、上滑和下滑手势,使用ACTION_MOVE是否可行? - Ramesh_D
@Ramesh_D 你需要生成大量的ACTION_MOVE事件来模拟滑动。 - Suragch
一个滑动操作可以通过 ACTION_DOWNACTION_MOVEACTION_UP 生成。 - rmtheis
我使用了这个,效果完美,onTouch事件被调用了,但是当我使用上述代码并按住手指在视图上移动时,ontouchevent没有被调用。 - Lakhwinder Singh
视图定义是什么? - Harrison Wu

6

这里是清晰版本:

public void TouchView(View view)
{
    view.DispatchTouchEvent(MotionEvent.Obtain(SystemClock.UptimeMillis(), SystemClock.UptimeMillis(), (int)MotionEventActions.Down, 0, 0, 0));
    view.DispatchTouchEvent(MotionEvent.Obtain(SystemClock.UptimeMillis(), SystemClock.UptimeMillis(), (int)MotionEventActions.Up, 0, 0, 0));
}

注:这是一份Xamarin Android解决方案,但你可以轻松修改为Java。


1
fun View.performTouchDown() = dispatchTouchEvent(MotionEvent
    .obtain(uptimeMillis(), uptimeMillis() + 700, ACTION_DOWN, 0f, 0f, 0))

1

补充一下@bstar55的优秀回答 - 如果你想创建一个“tap”事件,例如用户点击视图,则需要模拟用户在短时间内触摸屏幕并将手指移开。

为此,您需要“分派”ACTION_DOWN MotionEvent,然后在短时间后跟随ACTION_UP MotionEvent。

以下示例使用Kotlin编写,经过测试可靠:

   //Create amd send a tap event at the current target loctaion to the PhotoView
   //From testing (on an original Google Pixel) a tap event needs an ACTION_DOWN followed shortly afterwards by
   //an ACTION_UP, so send both events
   //First, create amd send the ACTION_DOWN MotionEvent
   var originalDownTime: Long = SystemClock.uptimeMillis()
   var eventTime: Long = SystemClock.uptimeMillis() + 100
   var x = your_X_Value
   var y = your_Y_Value 
   var metaState = 0
   var motionEvent = MotionEvent.obtain(
           originalDownTime,
           eventTime,
           MotionEvent.ACTION_DOWN,
           x,
           y,
           metaState
    )
    var returnVal = yourView.dispatchTouchEvent(motionEvent)
    Log.d(TAG,"rteurnVal: " + returnVal)

    //Create amd send the ACTION_UP MotionEvent
    eventTime= SystemClock.uptimeMillis() + 100
    motionEvent = MotionEvent.obtain(
           originalDownTime,
           eventTime,
           MotionEvent.ACTION_UP,
           x,
           y,
           metaState
     )
     returnVal = yourView.dispatchTouchEvent(motionEvent)
     Log.d(TAG,"rteurnVal: " + returnVal)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接