Начиная с обновления до Robolectric 4.3, onItemClickListener ListView получает нулевое представление - PullRequest
3 голосов
/ 04 июня 2019

Структура моей деятельности в основном такая (упрощенная для иллюстрации проблемы).По сути, для отображения ListView не достаточно места, если устройство имеет небольшой экран, потому что все места занимают другие представления:

<LinearLayout orientation="vertical">
    <SomeBigView
        layout_width="match_parent"
        layout_height="680dp"/>
    <ListView
        layout_width="match_parent"
        layout_height="wrap_content" />
</LinearLayout>

Мой код активности устанавливает прослушиватель щелчка элемента следующим образом:

list.onItemClickListener = AdapterView.OnItemClickListener { _, view, _, _ ->
    Snackbar.make(view, "Clicked on $view", Snackbar.LENGTH_SHORT).show()
}

Мой модульный тест касается первого элемента в списке:

val controller = Robolectric.buildActivity(MainActivity::class.java)
    .create().start().resume().visible()
val list: ListView = controller.get().findViewById(R.id.list)
shadowOf(list).performItemClick(0)

В Robolectric 4.2.1 мой прослушиватель щелчков вызывается с ненулевым значением view.В Robolectric 4.3 он вызывается с представлением null.

1 Ответ

3 голосов
/ 04 июня 2019

Сводка : Решение состоит в том, чтобы указать большую высоту устройства для этого теста с аннотацией @Config(qualifiers="h780dp").

Подробности : После некоторой отладки я обнаружилчто в Robolectric 4.2.1 высота ListView была 146 (top=680, bottom=826), а в Robolectric 4.3 - 0 (top=680, bottom=680).Высота устройства по умолчанию, используемая Robolectric, составляет 470, что недостаточно для отображения списка.Список не имеет дочерних представлений с Robolectric 4.3.

Реализация shadowOf(list).performItemClick(0) найдена в ShadowAdapterView от robolectric и составляет:

public boolean performItemClick(int position) {
    return realAdapterView.performItemClick(realAdapterView.getChildAt(position),
        position, realAdapterView.getItemIdAtPosition(position));
}

С Robolectric 4.3,getChildAt(position) возвращает null, то есть то, что пересылается прослушивателю щелчков.

Обходной путь - указать экран большего устройства для этого теста.Например:

@Test
@Config(qualifiers="h780dp")
...