diff --git a/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/focus/NestedFocusListenerTest.kt b/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/focus/NestedFocusListenerTest.kt index e7d0ca49..bbfdefef 100644 --- a/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/focus/NestedFocusListenerTest.kt +++ b/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/focus/NestedFocusListenerTest.kt @@ -19,6 +19,9 @@ package com.rubensousa.dpadrecyclerview.test.tests.focus import androidx.core.view.get import androidx.fragment.app.testing.FragmentScenario import androidx.fragment.app.testing.launchFragmentInContainer +import androidx.test.espresso.Espresso +import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.espresso.matcher.ViewMatchers.withTagValue import com.google.common.truth.Truth.assertThat import com.rubensousa.dpadrecyclerview.DpadRecyclerView import com.rubensousa.dpadrecyclerview.test.TestNestedListFragment @@ -29,7 +32,10 @@ import com.rubensousa.dpadrecyclerview.testfixtures.DpadFocusEvent import com.rubensousa.dpadrecyclerview.testfixtures.recording.ScreenRecorderRule import com.rubensousa.dpadrecyclerview.testing.KeyEvents import com.rubensousa.dpadrecyclerview.testing.R +import com.rubensousa.dpadrecyclerview.testing.actions.DpadRecyclerViewActions import com.rubensousa.dpadrecyclerview.testing.rules.DisableIdleTimeoutRule +import org.hamcrest.Matchers +import org.hamcrest.core.AllOf.allOf import org.junit.Before import org.junit.Rule import org.junit.Test @@ -127,6 +133,27 @@ class NestedFocusListenerTest { } } + @Test + fun testParentRecyclerViewStillReceivesFocusIfChildHasNoListener() { + // given + val focusEvents = 6 + Espresso.onView( + allOf( + withId(com.rubensousa.dpadrecyclerview.test.R.id.nestedRecyclerView), + withTagValue(Matchers.`is`(0)) + ) + ).perform(DpadRecyclerViewActions.execute("Clear listener") { recyclerView -> + recyclerView.clearOnViewFocusedListeners() + }) + + // when + KeyEvents.pressRight(times = focusEvents - 1) + waitForIdleScrollState() + + // then + assertThat(getParentFocusEvents()).hasSize(focusEvents) + } + private fun getChildFocusEvents(): List { var events = listOf() fragmentScenario.onFragment { fragment -> diff --git a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotSelector.kt b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotSelector.kt index a5badcaa..c7926f77 100644 --- a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotSelector.kt +++ b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotSelector.kt @@ -106,8 +106,8 @@ internal class PivotSelector( fun focus(view: View) { view.requestFocus() - // Exit early if there's no one listening for focus events - if (focusListeners.isEmpty() || isRetainingFocus) { + // Do not notify listeners if we are retaining focus + if (isRetainingFocus) { return } val currentRecyclerView = recyclerView ?: return @@ -213,10 +213,6 @@ internal class PivotSelector( return max(0, min(itemCount - 1, position)) } - fun onLayoutChildren(state: RecyclerView.State) { - - } - fun onLayoutCompleted() { if (isSelectionUpdatePending) { isSelectionUpdatePending = false