我正在尝试以编程方式触发视图中的滑动。还有其他问题的答案,但它们对我没有帮助。我还看到一些comments表示出于安全原因禁用了程序化拖动/滚动,是真的吗?我很乐意为此找到一个明确的答案。
我尝试了以下poster通过视频显示正常工作的方法,因此它应该正常工作! AndroidManifest
中是否需要我的东西?我也尝试过scrollBy()
API,但这不会滚动我的内容,而是将内容移到屏幕外。
此外,我已经在视图中注册了OnTouchListener
,并看到以下代码复制了相同格式的事件触发(ACTION_DOWN
,ACTION_MOVE
,ACTION_UP)
单击+拖动和鼠标滚轮都可以,尽管单击+拖动和鼠标滚轮可以工作,而编程式滚动/滑动不起作用。
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
final MotionEvent event = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_DOWN, 500, 700, 0);
dispatchTouchEvent(event);
event.recycle();
}
});
handler.postDelayed(new Runnable() {
@Override
public void run() {
final MotionEvent event = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_MOVE, 500, 700 ,0);
dispatchTouchEvent(event);
event.recycle();
}
}, 50);
handler.postDelayed(new Runnable() {
@Override
public void run() {
final MotionEvent event = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_MOVE, 500 ,700 + 400, 0);
dispatchTouchEvent(event);
event.recycle();
}
}, 100);
handler.postDelayed(new Runnable() {
@Override
public void run() {
final MotionEvent event = MotionEvent.obtain(System.currentTimeMillis(), System.currentTimeMillis(), MotionEvent.ACTION_UP, 500, 700 + 400, 0);
dispatchTouchEvent(event);
event.recycle();
}
}, 1000);
答案 0 :(得分:0)
使用androidx.test.uiautomator
完全有可能-这是现实情况。我已经编写了此方法来测试无尽的滚动RecyclerView
……只是因为我懒得滑动:
protected void fling(UiObject2 view, int speed, int pause) {
Assert.assertThat(view, not(equalTo(null)));
try {
view.fling(Direction.DOWN, speed);
} catch (StaleObjectException e) {
Assert.fail();
}
sleep(pause);
}
使用adb shell input swipe
进行事件自动化也是可以的...
在两种情况下,事件都不是来自经过测试的应用。
(在两种情况下)都依赖于android.permission.INJECT_EVENTS
。
在有根设备上,甚至不需要adb
-请参见answer。
答案 1 :(得分:0)
这是我的逃跑方法
/**
* Simulate touching a specific location and dragging to a new location.
*
* @param fromX X coordinate of the initial touch, in screen coordinates
* @param toX Xcoordinate of the drag destination, in screen coordinates
* @param fromY X coordinate of the initial touch, in screen coordinates
* @param toY Y coordinate of the drag destination, in screen coordinates
* @param stepCount How many move steps to include in the drag
*/
fun fling(
fromX: Float, toX: Float, fromY: Float,
toY: Float, stepCount: Int
) {
val inst = Instrumentation()
val downTime = SystemClock.uptimeMillis()
var eventTime = SystemClock.uptimeMillis()
var y = fromY
var x = fromX
val yStep = (toY - fromY) / stepCount
val xStep = (toX - fromX) / stepCount
var event = MotionEvent.obtain(
downTime, eventTime,
MotionEvent.ACTION_DOWN, fromX, fromY, 0
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
event.source = InputDevice.SOURCE_TOUCHSCREEN
}
inst.sendPointerSync(event)
for (i in 0 until stepCount) {
y += yStep
x += xStep
eventTime = SystemClock.uptimeMillis()
event = MotionEvent.obtain(
downTime, eventTime + stepCount,
MotionEvent.ACTION_MOVE, x, y, 0
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
event.source = InputDevice.SOURCE_TOUCHSCREEN
}
inst.sendPointerSync(event)
}
eventTime = SystemClock.uptimeMillis() + stepCount.toLong() + 2
event = MotionEvent.obtain(
downTime, eventTime,
MotionEvent.ACTION_UP, toX, toY, 0
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
event.source = InputDevice.SOURCE_TOUCHSCREEN
}
inst.sendPointerSync(event)
}
这就是我的用法
fab.setOnClickListener { view ->
Thread(Runnable {
try {
fling(500f ,900f ,530f ,20f, 5);
// emulateMptionEvent()
} catch (e: Exception) {
}
}).start()
}
这是它的工作方式:
之前
单击Fab按钮后,蓝色虚线将模拟飞行路径。