Android Robolectric Click RecyclerView Item

Есть ли способ с помощью Robolectric имитировать щелчок по элементу RecyclerView?

До сих пор я пытался получить View в первой видимой позиции RecyclerView, но это всегда null. Это getChildCount() постоянно возвращает 0, а findViewHolderForPosition всегда null. Адаптер возвращает число, отличное от 0, из getItemCount() (в адаптере определенно есть элементы).

Я использую Robolectric 2.4 SNAPSHOT.


person Eliezer    schedule 21.11.2014    source источник


Ответы (4)


Похоже, проблема заключалась в том, что RecyclerView нужно измерять и выкладывать вручную в Robolectric. Вызов этого решает проблему:

recyclerView.measure(0, 0);
recyclerView.layout(0, 0, 100, 10000);
person Eliezer    schedule 21.11.2014
comment
Это отличная находка. Спасибо тебе за это. Могу я спросить, как вы обнаружили, что представление переработчика не было измерено и выложено? Это было бы очень полезно для меня. - person c05mic; 25.12.2014
comment
Где вы добавляете меру и макет? после findViewById в самом тесте? - person Jeroen; 14.04.2015
comment
Для этого нет конкретного места; Иногда я делаю это после findViewById, но обычно я делаю это прямо перед тем, как мне это нужно. - person Eliezer; 14.04.2015
comment
Кроме того, этот код следует вызывать столько раз, сколько вы вызывали notifyDatasetChanged() или аналогичный метод на адаптере, а не только один раз. Это только что случилось со мной. - person Vince; 04.11.2015
comment
Привет @Eliezer, спасибо за ответ. Я искал некоторое время, и это сработало. Если можно, то как вы это выяснили? Я хотел бы знать, чтобы расширить свои знания об Android. - person Killesk; 13.04.2017
comment
@Элиэзер Спасибо за ответ. Это хорошо работает для меня. - person Qian Sijianhao; 28.07.2017

С Robolectric 3 вы можете использовать visible():

ActivityController<MyActivity> activityController = Robolectric.buildActivity(MyActivityclass);
activityController.create().start().visible();

ShadowActivity myActivityShadow = shadowOf(activityController.get()); 

RecyclerView currentRecyclerView = ((RecyclerView) myActivityShadow.findViewById(R.id.myrecyclerid));
    currentRecyclerView.getChildAt(0).performClick();

Это устраняет необходимость инициировать измерение вида вручную.

person Marco Hertwig    schedule 26.03.2017

Расширение ответа Marco Hertwig:

Вам нужно добавить recyclerView к действию, чтобы его методы макета вызывались должным образом. Вы можете вызвать их вручную (как в ответе Elizer), но вам придется управлять состоянием самостоятельно. Кроме того, это не будет имитацией реального варианта использования.

Код:

@Before
public void setup() {
    ActivityController<Activity> activityController = 
        Robolectric.buildActivity(Activity.class); // setup a default Activity
    Activity activity = activityController.get();

    /*
    Setup the recyclerView (create it, add the adapter, add a LayoutManager, etc.)
    ...
    */

    // set the recyclerView object as the only view in the activity
    activity.setContentView(recyclerView);

    // start the activity
    activityController.create().start().visible();
}

Теперь вам не нужно беспокоиться о вызове layout и measure каждый раз, когда ваш recyclerView обновляется (например, путем добавления/удаления элементов из adapter).

person vedant    schedule 22.11.2017

Просто вызовите

Robolectric.flushForegroundThreadScheduler()

перед выполнениемClick(), чтобы гарантировать, что все операции пользовательского интерфейса (включая этапы измерения и макета представления ресайклера после заполнения набором данных) завершены

person Alexander Bernat    schedule 06.07.2021