Выбор дочернего вида по индексу с помощью эспрессо

Другой слой косвенности:

for i in $(eval echo {1..$END}); do
    ∶
29
задан tomrozb 29 July 2014 в 21:45
поделиться

3 ответа

 public static Matcher<View> nthChildOf(final Matcher<View> parentMatcher, final int childPosition) {
    return new TypeSafeMatcher<View>() {
      @Override
      public void describeTo(Description description) {
        description.appendText("with "+childPosition+" child view of type parentMatcher");
      }

      @Override
      public boolean matchesSafely(View view) {
        if (!(view.getParent() instanceof ViewGroup)) {
          return parentMatcher.matches(view.getParent());
        }

        ViewGroup group = (ViewGroup) view.getParent();
        return parentMatcher.matches(view.getParent()) && group.getChildAt(childPosition).equals(view);
      }
    };
  }

Чтобы использовать его

onView(nthChildOf(withId(R.id.parent_container), 0)).check(matches(withText("I am the first child")));
59
ответ дан vilpe89 29 July 2014 в 21:45
поделиться

Чтобы попытаться немного улучшить решение Maragues, я внес несколько изменений.

Решение состоит в том, чтобы создать пользовательский Matcher < View > , который оборачивает другой Matcher < View > для родительского представления и принимает индекс дочернего представления для сопоставления.

public static Matcher<View> nthChildOf(final Matcher<View> parentMatcher, final int childPosition) {
    return new TypeSafeMatcher<View>() {
        @Override
        public void describeTo(Description description) {
            description.appendText("position " + childPosition + " of parent ");
            parentMatcher.describeTo(description);
        }

        @Override
        public boolean matchesSafely(View view) {
            if (!(view.getParent() instanceof ViewGroup)) return false;
            ViewGroup parent = (ViewGroup) view.getParent();

            return parentMatcher.matches(parent)
                    && parent.getChildCount() > childPosition
                    && parent.getChildAt(childPosition).equals(view);
        }
    };
}

Подробное объяснение

Вы можете переопределить метод attributeTo , чтобы дать простое для понимания описание сопоставителя, добавив к Описание Аргумент. Вы также захотите передать вызов descriptionTo родительскому сопоставителю, чтобы его описание также было добавлено.

@Override
public void describeTo(Description description) {
    description.appendText("position " + childPosition + " of parent "); // Add this matcher's description.
    parentMatcher.describeTo(description); // Add the parentMatcher description.
}

Далее следует переопределить matchSafely , который будет определять, когда найдено совпадение в иерархии представлений. При вызове с представлением, чей родитель соответствует предоставленному сопоставлению родителей, убедитесь, что представление равно потомку в предоставленной позиции.

Если родитель не имеет childCount больше, чем дочерняя позиция, getChildAt вернет ноль и вызовет сбой теста. Лучше избегать сбоев и позволить тесту провалиться, чтобы мы получили надлежащий отчет о тестировании и сообщение об ошибке.

@Override
public boolean matchesSafely(View view) {
if (!(view.getParent() instanceof ViewGroup)) return false; // If it's not a ViewGroup we know it doesn't match.
    ViewGroup parent = (ViewGroup) view.getParent();

    return parentMatcher.matches(parent) // Check that the parent matches.
            && parent.getChildCount() > childPosition // Make sure there's enough children.
            && parent.getChildAt(childPosition).equals(view); // Check that this is the right child.
}
21
ответ дан eski 29 July 2014 в 21:45
поделиться

Если вы можете получить родительский вид. Может быть, эта ссылка , в которой определено совпадение для получения первого потомка представления, может дать вам некоторую подсказку.

     public static Matcher<View> firstChildOf(final Matcher<View> parentMatcher) {
        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("with first child view of type parentMatcher");
            }

            @Override
            public boolean matchesSafely(View view) {       

                if (!(view.getParent() instanceof ViewGroup)) {
                    return parentMatcher.matches(view.getParent());                   
                }
                ViewGroup group = (ViewGroup) view.getParent();
                return parentMatcher.matches(view.getParent()) && group.getChildAt(0).equals(view);

            }
        };
    }
11
ответ дан Nick Dong 29 July 2014 в 21:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: