gpt4 book ai didi

android - 如何为 Android 测试生成缩放/捏合手势

转载 作者:IT老高 更新时间:2023-10-28 23:10:48 25 4
gpt4 key购买 nike

我正在尝试生成缩放/捏合手势进行测试,我尝试使用 Android API MotionEvent.obtain(),但发现很难实现缩放/捏合事件。

我从 MotionEvent.obtain 引用了 API .你能告诉我正确的方法吗?

这是我的实现:

//for zoom, we need four points coordinations: start0, start1, end0, end1

Instrumentation inst;

// action down event
MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, 1, prop_start0, pointerCoords_start0, 0, 0, 0, 0, 0, 0, 0, 0 );
inst.sendPointerSync(event);

// action pointer 2 down event
event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_2_DOWN, 2, properties_start0_1, pointerCoords_start0_1, 0, 0, 0, 0, 0, 0, 0, 0);
inst.sendPointerSync(event);

// action move events
duration = 1000; //1000 ms
event_interval = 10;//time interval between consecutive events 10ms
moveEventNum = duration / event_interval;
stepx0 = (end0.x - start0.x)/moveEventNum;
stepy0 = (end0.y - start0.y)/moveEventNum;
stepx1 = (end1.x - start1.x)/moveEventNum;
stepy1 = (end1.y - start1.y)/moveEventNum;

move_event0= start0;
move_event1 = start1;
for ( int i = 0; i < moveEventNum; i++) {
// [generate middle points here ]
mov_event0.x += stepx0;
mov_event0.y += stepy0;
mov_event1.x += stepx1;
mov_event1.y += stepy1;

eventTime += event_interval;

event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, 2, properties_move_event, pointerCoords_move_event0_1, 0, 0, 0, 0, 0, 0, 0, 0);

inst.sendPointerSync(event);
}

event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_POINTER_2_UP, 2, properties_end0_1, pointerCoords_end0_1, 0, 0, 0, 0, 0, 0, 0, 0);
inst.sendPointerSync(event);

event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, 1, end1, pointerCoords_end1, 0, 0, 0, 0, 0, 0, 0, 0 );
inst.sendPointerSync(event);

最佳答案

嗯,我找到了问题。

问题:

在使用obtain() API时,我们必须在每个事件中设置点的压力和大小。

对于

obtain(long, long, int, int, android.view.MotionEvent.PointerProperties[], 
android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int)

PointerCoords[],我们要设置压力和大小为1,默认值为0。

对于

public static MotionEvent obtain (long downTime, long eventTime, int action,
float x, float y, int metaState)

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).

since the default pressure and size are 1, so we don't need to set them.

创建手势的技巧:

1.遵循真实的手势序列,因为我们要模拟真实的手势

  • 重写 onTouchEvent() 来检查接收到的真实事件应用。这些事件也可以用来比较真实的用户触摸事件和生成的触摸事件 以浏览器为例示例:

    a) @Override public boolean onTouchEvent(MotionEvent event) { Log.i("WebView", event.toString() + event.getAction()); bool 值 = super.onTouchEvent(事件);返回rt; }

  • 手动触摸屏幕从a)中的onTouchEvent()获取真正的手势序列。我们可以在生成事件时遵循事件顺序。-- 如果我们不遵循手势事件序列,检测到的事件可能会被拒绝。

  • 这是一个有效的缩放手势事件序列,(所有事件的downTime都是一样的)

    我。 ACTION_DOWN 一个起点

    二。两个起点的ACTION_POINTER_2_DOWN

    iii.ACTION_MOVE 两个中间点

    四。 ACTION_POINTER_2_UP 两个端点

    v.一个端点的 ACTION_UP

<强>2。正确使用 API MotionEvent.获取

  • 有两个最常用的obtain() API。

public static MotionEvent 获取 (long downTime, long eventTime, int action, float x, float y,int 元状态)

public static MotionEvent 获取(long, long, int, int, android.view.MotionEvent.PointerProperties[],android.view.MotionEvent.PointerCoords[], int, int, float, float, int, int, int, int)

第一个通常用于单点手势,如滑动、滚动、单击等。此功能的参数(压力、大小、xPresion、yPresion)均设​​置为1。

第二个是更通用的一个,可以用于多点触控事件的生成。而对于第二个,我们必须将每个触摸点的pointerCoords中的压力,大小设置为1。

以下是生成缩放手势的示例:

public static void generateZoomGesture(Instrumentation inst,
long startTime, boolean ifMove, GestureInfo.Point startPoint1,
GestureInfo.Point startPoint2, GestureInfo.Point endPoint1,
GestureInfo.Point endPoint2, int duration) {

if (inst == null || startPoint1 == null
|| (ifMove && endPoint1 == null)) {
return;
}

long eventTime = startTime;
long downTime = startTime;
MotionEvent event;
float eventX1, eventY1, eventX2, eventY2;

eventX1 = startPoint1.x;
eventY1 = startPoint1.y;
eventX2 = startPoint2.x;
eventY2 = startPoint2.y;

// specify the property for the two touch points
PointerProperties[] properties = new PointerProperties[2];
PointerProperties pp1 = new PointerProperties();
pp1.id = 0;
pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
PointerProperties pp2 = new PointerProperties();
pp2.id = 1;
pp2.toolType = MotionEvent.TOOL_TYPE_FINGER;

properties[0] = pp1;
properties[1] = pp2;

//specify the coordinations of the two touch points
//NOTE: you MUST set the pressure and size value, or it doesn't work
PointerCoords[] pointerCoords = new PointerCoords[2];
PointerCoords pc1 = new PointerCoords();
pc1.x = eventX1;
pc1.y = eventY1;
pc1.pressure = 1;
pc1.size = 1;
PointerCoords pc2 = new PointerCoords();
pc2.x = eventX2;
pc2.y = eventY2;
pc2.pressure = 1;
pc2.size = 1;
pointerCoords[0] = pc1;
pointerCoords[1] = pc2;

//////////////////////////////////////////////////////////////
// events sequence of zoom gesture
// 1. send ACTION_DOWN event of one start point
// 2. send ACTION_POINTER_2_DOWN of two start points
// 3. send ACTION_MOVE of two middle points
// 4. repeat step 3 with updated middle points (x,y),
// until reach the end points
// 5. send ACTION_POINTER_2_UP of two end points
// 6. send ACTION_UP of one end point
//////////////////////////////////////////////////////////////

// step 1
event = MotionEvent.obtain(downTime, eventTime,
MotionEvent.ACTION_DOWN, 1, properties,
pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0 );

inst.sendPointerSync(event);

//step 2
event = MotionEvent.obtain(downTime, eventTime,
MotionEvent.ACTION_POINTER_2_DOWN, 2,
properties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);

inst.sendPointerSync(event);

//step 3, 4
if (ifMove) {
int moveEventNumber = 1;
moveEventNumber = duration / EVENT_MIN_INTERVAL;

float stepX1, stepY1, stepX2, stepY2;

stepX1 = (endPoint1.x - startPoint1.x) / moveEventNumber;
stepY1 = (endPoint1.y - startPoint1.y) / moveEventNumber;
stepX2 = (endPoint2.x - startPoint2.x) / moveEventNumber;
stepY2 = (endPoint2.y - startPoint2.y) / moveEventNumber;

for (int i = 0; i < moveEventNumber; i++) {
// update the move events
eventTime += EVENT_MIN_INTERVAL;
eventX1 += stepX1;
eventY1 += stepY1;
eventX2 += stepX2;
eventY2 += stepY2;

pc1.x = eventX1;
pc1.y = eventY1;
pc2.x = eventX2;
pc2.y = eventY2;

pointerCoords[0] = pc1;
pointerCoords[1] = pc2;

event = MotionEvent.obtain(downTime, eventTime,
MotionEvent.ACTION_MOVE, 2, properties,
pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);

inst.sendPointerSync(event);
}
}

//step 5
pc1.x = endPoint1.x;
pc1.y = endPoint1.y;
pc2.x = endPoint2.x;
pc2.y = endPoint2.y;
pointerCoords[0] = pc1;
pointerCoords[1] = pc2;

eventTime += EVENT_MIN_INTERVAL;
event = MotionEvent.obtain(downTime, eventTime,
MotionEvent.ACTION_POINTER_2_UP, 2, properties,
pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);
inst.sendPointerSync(event);

// step 6
eventTime += EVENT_MIN_INTERVAL;
event = MotionEvent.obtain(downTime, eventTime,
MotionEvent.ACTION_UP, 1, properties,
pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0 );
inst.sendPointerSync(event);
}

关于android - 如何为 Android 测试生成缩放/捏合手势,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11523423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com