web-dev-qa-db-ja.com

Espressoを使用してRecyclerViewアイテム内のビューをクリックする

エスプレッソを使用してRecyclerViewアイテム内の特定のビューをクリックするにはどうすればよいですか?私は次を使用して位置0のアイテムをクリックできることを知っています:

onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));

ただし、アイテム自体ではなく、そのアイテム内の特定のビューをクリックする必要があります。

前もって感謝します。

-編集-

もっと正確に言うと、RecyclerViewR.id.recycler_view)の項目はCardViewR.id.card_view)です。各CardViewの中に(特に)4つのボタンがあり、特定のボタン(R.id.bt_deliver)をクリックしたい。

Espresso 2.0の新機能を使用したいのですが、それが可能かどうかわかりません。

不可能な場合は、次のようなものを使用します(Thomas Kellerコードを使用)。

onRecyclerItemView(R.id.card_view, ???, withId(R.id.bt_deliver)).perform(click());

しかし、疑問符を何に付ければよいかわかりません。

86
Filipe Ramos

ビューアクションのカスタマイズで実行できます。

public class MyViewAction {

    public static ViewAction clickChildViewWithId(final int id) {
        return new ViewAction() {
            @Override
            public Matcher<View> getConstraints() {
                return null;
            }

            @Override
            public String getDescription() {
                return "Click on a child view with specified id.";
            }

            @Override
            public void perform(UiController uiController, View view) {
                View v = view.findViewById(id);
                v.performClick();
            }
        };
    }

}

それからあなたはそれをクリックすることができます

onView(withId(R.id.rv_conference_list)).perform(
            RecyclerViewActions.actionOnItemAtPosition(0, MyViewAction.clickChildViewWithId(R.id. bt_deliver)));
119
blade

Android.support.test.espresso.contribにより、より簡単になりました。

1)テストの依存関係を追加する

androidTestCompile('com.Android.support.test.espresso:espresso-contrib:2.0') {
    exclude group: 'com.Android.support', module: 'appcompat'
    exclude group: 'com.Android.support', module: 'support-v4'
    exclude module: 'recyclerview-v7'
}

* 3つのモジュールを除外します。既にお持ちの可能性が高いためです。

2)その後、次のようなことをします

onView(withId(R.id.recycler_grid))
            .perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));

または

onView(withId(R.id.recyclerView))
  .perform(RecyclerViewActions.actionOnItem(
            hasDescendant(withText("whatever")), click()));

または

onView(withId(R.id.recycler_linear))
            .check(matches(hasDescendant(withText("whatever"))));
58
Andrey

次のアプローチを試してください:

    onView(withRecyclerView(R.id.recyclerView)
                    .atPositionOnView(position, R.id.bt_deliver))
                    .perform(click());

    public static RecyclerViewMatcher withRecyclerView(final int recyclerViewId) {
            return new RecyclerViewMatcher(recyclerViewId);
    }

public class RecyclerViewMatcher {
    final int mRecyclerViewId;

    public RecyclerViewMatcher(int recyclerViewId) {
        this.mRecyclerViewId = recyclerViewId;
    }

    public Matcher<View> atPosition(final int position) {
        return atPositionOnView(position, -1);
    }

    public Matcher<View> atPositionOnView(final int position, final int targetViewId) {

        return new TypeSafeMatcher<View>() {
            Resources resources = null;
            View childView;

            public void describeTo(Description description) {
                int id = targetViewId == -1 ? mRecyclerViewId : targetViewId;
                String idDescription = Integer.toString(id);
                if (this.resources != null) {
                    try {
                        idDescription = this.resources.getResourceName(id);
                    } catch (Resources.NotFoundException var4) {
                        idDescription = String.format("%s (resource name not found)", id);
                    }
                }

                description.appendText("with id: " + idDescription);
            }

            public boolean matchesSafely(View view) {

                this.resources = view.getResources();

                if (childView == null) {
                    RecyclerView recyclerView =
                            (RecyclerView) view.getRootView().findViewById(mRecyclerViewId);
                    if (recyclerView != null) {

                        childView = recyclerView.findViewHolderForAdapterPosition(position).itemView;
                    }
                    else {
                        return false;
                    }
                }

                if (targetViewId == -1) {
                    return view == childView;
                } else {
                    View targetView = childView.findViewById(targetViewId);
                    return view == targetView;
                }

            }
        };
    }
}
6
Sergey

ここに、私がkotlinで問題を解決した方法があります:

fun clickOnViewChild(viewId: Int) = object : ViewAction {
    override fun getConstraints() = null

    override fun getDescription() = "Click on a child view with specified id."

    override fun perform(uiController: UiController, view: View) = click().perform(uiController, view.findViewById<View>(viewId))
}

その後

onView(withId(R.id.recyclerView)).perform(RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(position, clickOnViewChild(R.id.viewToClickInTheRow)))
4
user2768856

クリック on 番目の項目 of recyclerView次のようにできます。

onView(withId(R.id.recyclerView)).perform(
                RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(2,click()))

忘れないでくださいを実行して、推論が失敗しないようにViewHolderタイプを指定します。

2
erluxman