私のアプリケーションでは、ユーザがリスト内の項目を並べ替えることができるようにしました。ドラッグしてドラッグしてドラッグ・シャドウを作成すると、選択した位置で一旦落とすと、アイテムは並べ替えられます。AndroidのUIテスト長いクリックとドラッグ
私はこのためのUIテストを開発するのに苦労しています。ドラッグ・シャドウを作成するため、またはドラッグ・モーションを実装するために、項目を長時間クリックすることができます。私は2つを組み合わせて1つの動きにすることはできないようです。
私はAndroid UIテストでEspressoとBaristaを使用しています。私はバリスタのAPIを使用長いクリックのために
:ドラッグの動きを
longClickOn("ITEM");
を、私は私自身のエスプレッソViewActionを作成しようとしました:
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(ViewGroup.class);
}
@Override
public String getDescription() {
return "Swiping child " + srcIndex + " to child " + destIndex;
}
@Override
public void perform(UiController uiController, View view) {
ViewGroup parent = (ViewGroup) view;
final View srcChild = parent.getChildAt(srcIndex);
final View destChild = parent.getChildAt(destIndex);
final CoordinatesProvider srcCoordinatesProvider = new CoordinatesProvider() {
@Override
public float[] calculateCoordinates(View view) {
int[] location = new int[2];
srcChild.getLocationInWindow(location);
float x = location[0] + (view.getMeasuredWidth()/2);
float y = location[1] + (view.getMeasuredHeight()/2);
return new float[] {x, y};
}
};
final CoordinatesProvider destCoordinatesProvider = new CoordinatesProvider() {
@Override
public float[] calculateCoordinates(View view) {
int[] location = new int[2];
destChild.getLocationInWindow(location);
float x = location[0] + (view.getMeasuredWidth()/2);
float y = location[1] + (view.getMeasuredHeight()/2);
return new float[] {x, y};
}
};
GeneralSwipeAction swipe = new GeneralSwipeAction(Swipe.FAST,
srcCoordinatesProvider, destCoordinatesProvider, Press.FINGER);
swipe.perform(uiController, parent);
}
};
EDIT:
@ Bee_Negativeの答えに続いて、私は与えられた答えをカスタマイズし、これを思いついた:
private static ViewAction drag(final int srcIndex, final int destIndex) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(ViewGroup.class);
}
@Override
public String getDescription() {
return "Swiping child " + srcIndex + " to child " + destIndex;
}
@Override
public void perform(UiController uiController, View view) {
ViewGroup parent = (ViewGroup) view;
uiController.loopMainThreadUntilIdle();
final View srcChild = parent.getChildAt(srcIndex);
final View destChild = parent.getChildAt(destIndex);
final CoordinatesProvider coordinatesProvider = getCoordinatesProdvider();
float[] precision = Press.PINPOINT.describePrecision();
MotionEvent downEvent = MotionEvents.sendDown(uiController, coordinatesProvider.calculateCoordinates(srcChild), precision).down;
try {
long longPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5);
uiController.loopMainThreadForAtLeast(longPressTimeout);
float[][] steps = interpolateDragging(
coordinatesProvider.calculateCoordinates(srcChild),
coordinatesProvider.calculateCoordinates(destChild)
);
uiController.loopMainThreadUntilIdle();
for(float[] step : steps) {
if(!MotionEvents.sendMovement(uiController, downEvent, step)) {
MotionEvents.sendCancel(uiController, downEvent);
}
}
if(!MotionEvents.sendUp(uiController, downEvent, coordinatesProvider.calculateCoordinates(destChild))) {
MotionEvents.sendCancel(uiController, downEvent);
}
} catch(Exception e) {
System.out.println(e);
} finally {
downEvent.recycle();
}
}
};
}
次のようにUnforunately、それはMotionEvents.sendMovement
でエラーがスローされます。ここでは
Error performing 'inject motion event (corresponding down event: MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=540.0, y[0]=302.0, toolType[0]=TOOL_TYPE_UNKNOWN, buttonState=BUTTON_PRIMARY, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=34586525, downTime=34586525, deviceId=0, source=0x1002 })' on view 'unknown'.
ありがとうございました。残念ながら、それはまだかなり働いていません。詳細については私の編集をチェックしてください。 –
システムのUI要素(キーボード、通知パネル、または下部のボタンバー)のいずれかに触れ始めるようです。私はあなたのビューアクションにスクロールを組み込む必要があると思う。私の場合、私はリサイクラビューを使用していて、アイテムがドラッグされているアイテムにスクロールしていました。 recyclerviewにいない場合は、[ScrollToAction](https://android.googlesource.com/platform/frameworks/testing/+/android-support-test/espresso/core/src/main/java/android)を使用できます。 /support/test/espresso/action/ScrollToAction.java)を参照として –
実際には、あなたのカスタム 'ViewMatchers.withParentIndex()'からビューアクションを呼び出すことは便利かもしれませんし、与えられたものとちょうど一致する独自のマッチャーを書くこともできますビュー(デフォルトではエスプレッソであり、悪用される可能性のあるマッチャーは正当に提供されません) –