*我正在编写单元测试用例以测试recyclerview项的向左滑动。我尝试使用此代码。但这不起作用
代码段:
float x = 0.0f;
float y = 0.0f;
int metaState = 0;
MotionEvent event = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_DOWN,
x,
y,
metaState
);
MotionEvent moveEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_MOVE,
30,
y,
metaState
);
MotionEvent upEvent = MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_UP,
x,
y,
metaState
);
recylerView.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.regular_card).dispatchTouchEvent(event);
recylerView.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.regular_card).dispatchTouchEvent(moveEvent);
recylerView.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.regular_card).dispatchTouchEvent(upEvent);*
答案 0 :(得分:0)
此扩展功能可以为您提供帮助:
fun ViewGroup.performSwipeToLeft(target: View) {
this.performSwipe(target, distanceX = -this.width * .5f, distanceY = 0f)
}
fun ViewGroup.performSwipeToRight(target: View) {
this.performSwipe(target, distanceX = +this.width * .5f, distanceY = 0f)
}
fun ViewGroup.performSwipeToTop(target: View) {
this.performSwipe(target, distanceX = 0f, distanceY = -this.height * .5f)
}
fun ViewGroup.performSwipeToBottom(target: View) {
this.performSwipe(target, distanceX = 0f, distanceY = +this.width * .5f)
}
fun ViewGroup.performSwipe(target: View, distanceX: Float, distanceY: Float) {
val parentCoords = intArrayOf(0, 0)
this.getLocationInWindow(parentCoords)
val childCoords = intArrayOf(0, 0)
target.getLocationInWindow(childCoords)
val initGlobalX = childCoords[0].toFloat() + 1f
val initGlobalY = childCoords[1].toFloat() + 1f
val initLocalX = (childCoords[0] - parentCoords[0]).toFloat() + 1f
val initLocalY = (childCoords[1] - parentCoords[1]).toFloat() + 1f
val downTime = SystemClock.uptimeMillis()
var eventTime = SystemClock.uptimeMillis()
this.dispatchTouchEvent(
MotionEvent.obtain(
downTime,
eventTime,
MotionEvent.ACTION_DOWN,
initGlobalX,
initGlobalY,
0
).apply {
setLocation(initLocalX, initLocalY)
source = InputDevice.SOURCE_TOUCHSCREEN
}
)
val steps = 20
var i = 0
while (i in 0..steps) {
val globalX = initGlobalX + i * distanceX / steps
val globalY = initGlobalY + i * distanceY / steps
val localX = initLocalX + i * distanceX / steps
val localY = initLocalY + i * distanceY / steps
if (globalX <= 10f || globalY <= 10f) {
break
}
this.dispatchTouchEvent(
MotionEvent.obtain(
downTime,
++eventTime,
MotionEvent.ACTION_MOVE,
globalX,
globalY,
0
).apply {
setLocation(localX, localY)
source = InputDevice.SOURCE_TOUCHSCREEN
}
)
i++
}
this.dispatchTouchEvent(
MotionEvent.obtain(
downTime,
++eventTime,
MotionEvent.ACTION_UP,
initGlobalX + i * distanceX,
initGlobalY + i * distanceY,
0
).apply {
setLocation(initLocalX + i * distanceX, initLocalY + i * distanceY)
source = InputDevice.SOURCE_TOUCHSCREEN
}
)
}
在您的情况下,您可以按以下方式使用它:
recylerView.performSwipeToLeft(recyclerView.getChildAt(0))
滑动动画也可以与SystemClock.uptimeMillis()
绑定。因此,您需要在测试前添加@LooperMode(LooperMode.Mode.PAUSED)
,然后使用ShadowSystemClock.advanceBy
就我而言,是:
@Test
@LooperMode(LooperMode.Mode.PAUSED)
fun swipeItem_itemDeleted() {
......
listView.performSwipeToLeft(listView.getChildAt(1))
while (!ShadowLooper.getShadowMainLooper().isIdle) {
ShadowSystemClock.advanceBy(Duration.ofMillis(5))
try {
ShadowLooper.runMainLooperOneTask()
} catch (e: Exception) {
e.printStackTrace()
}
}
assertEquals(... )
}