2

У меня есть ListView:Как я могу нажать на View в ListView позиции конкретных строк

enter image description here

И я хочу, чтобы нажать на конкретную кнопку внутри ListView.

Если я хочу, чтобы выбрать с помощью переключателя Ondata:

onData(withId(R.id.button)) 
       .inAdapterView(withId(R.id.list_view)) 
       .atPosition(1) 
       .perform(click()); 

И я получаю эту ошибку:

android.support.test.espresso.PerformException: Error performing 'load adapter data' on view 'with id: com.example.application:id/list_view'. 
... 

Как я могу решить эту проблему?

ответ

5

onData() требует объекта Matcher для элемента, который вы заинтересованы в Если вы не заботитесь о данных адаптера вы можете использовать Matchers.anything() для эффективной. сопоставить все объекты в адаптере. В качестве альтернативы вы можете создать сопоставление данных (в зависимости от данных, которые хранятся в адаптере) для вашего элемента и передать его для более детерминированного теста.

Что касается кнопки - то, что вы ищете является onChildsView() метод, который позволяет передавать viewmatcher для потомка ListItem, что был подобран в onData().atPosition()

И как результат ваш тест будет выглядеть что-то вроде этого:

onData(anything()).inAdapterView(withId(R.id.list_view)) 
      .atPosition(1) 
      .onChildView(withId(R.id.button)) 
      .perform(click()); 
+0

Спасибо! Раньше я не видел этого onChildsView. Кстати, функция nthChildDescendant может быть полезна для других вещей :) –

0

Я использовал обходное решение, которое не использует данные ListView, а .getPosition(index) вместо этого проверяет, что представление с конкретным идентификатором является потомком вида ViewView конкретной позиции.

public static Matcher<View> nthChildsDescendant(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) { 

      while(view.getParent() != null) { 
       if(parentMatcher.matches(view.getParent())) { 
        return view.equals(((ViewGroup) view.getParent()).getChildAt(childPosition)); 
       } 
       view = (View) view.getParent(); 
      } 

      return false; 
     } 
    }; 
} 

Пример использования:

onView(allOf(
     withId(R.id.button), 
     nthChildsDescendant(withId(R.id.list_view), 1))) 
    .perform(click());