Skip to content

Commit

Permalink
Merge pull request #295 from rubensousa/selection_listeners
Browse files Browse the repository at this point in the history
Selection listeners
  • Loading branch information
rubensousa authored Feb 10, 2025
2 parents ef9013d + d2793f3 commit ca5a3d2
Show file tree
Hide file tree
Showing 32 changed files with 71 additions and 65 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ jobs:
./gradlew --build-cache dpadrecyclerview:connectedDebugAndroidTest
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.api-level }}-${{ matrix.arch }}-instrumentation-test-results
path: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ jobs:
./scripts/uninstall_test_services.sh
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.api-level }}-${{ matrix.arch }}-instrumentation-test-results
path: |
Expand Down
22 changes: 22 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## Version 1.4.1

2025-02-11

#### Bug fixes

- Fixed layout inconsistency when scrolling if `Edge.Min` is used for parent alignment. ([#291](https://github.com/rubensousa/DpadRecyclerView/pull/291))

#### API changes

- Breaking change: Now DpadRecyclerView is passed in `OnViewHolderSelectedListener` and `OnChildLaidOutListener` instead of plain `RecyclerView`.

## Version 1.4.0

### 1.4.0
Expand All @@ -8,6 +20,16 @@

- No changes since `1.4.0-rc02`

#### Important changes since 1.3.0

- Added `setItemSpacing`, `setItemEdgeSpacing` and other spacing setters to `DpadRecyclerView`. Documentation available [here](recipes/spacing.md).
- Added `onViewHolderDeselected` to `OnViewHolderSelectedListener`
- Added `OnFocusLostListener` to observe focus losses of `DpadRecyclerView`
- Added `DpadRecyclerView.setAlignmentLookup` to customize the alignment for individual positions and bypassing the default alignment configurations
- Improved `Modifier.dpadClickable` to support long clicks
- New `DpadScrollableLayout` for screens that need a scrollable header at the same level as a `DpadRecyclerView`
- Testing: Added `KeyEvents.longClick` to trigger long clicks from tests

### 1.4.0-rc02

2024-11-15
Expand Down
4 changes: 2 additions & 2 deletions docs/getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ You can observe selection changes using the following:
```kotlin linenums="1"
recyclerView.addOnViewHolderSelectedListener(object : OnViewHolderSelectedListener {
override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
) {}

override fun onViewHolderSelectedAndAligned(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down
4 changes: 2 additions & 2 deletions docs/migrating_leanback.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,14 @@ The child alignment APIs from `BaseGridView` can now be found in the `ChildAlign
```kotlin linenums="1"
recyclerView.addOnViewHolderSelectedListener(object : OnViewHolderSelectedListener {
override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
) {}

override fun onViewHolderSelectedAndAligned(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down
4 changes: 2 additions & 2 deletions docs/selection.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ You can observe selection changes using the following:
```kotlin linenums="1"
recyclerView.addOnViewHolderSelectedListener(object : OnViewHolderSelectedListener {
override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
) {}

override fun onViewHolderSelectedAndAligned(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import androidx.compose.ui.test.onNodeWithText
import androidx.test.espresso.Espresso
import androidx.test.espresso.matcher.ViewMatchers.withId
import com.google.common.truth.Truth.assertThat
import com.rubensousa.dpadrecyclerview.testfixtures.DefaultInstrumentedReportRule
import com.rubensousa.dpadrecyclerview.testing.KeyEvents
import com.rubensousa.dpadrecyclerview.testing.assertions.DpadViewAssertions
import org.junit.Before
Expand All @@ -17,9 +16,6 @@ import org.junit.Test

class DpadClickableIntegrationTest {

@get:Rule(order = -1)
val report = DefaultInstrumentedReportRule()

@get:Rule
val composeTestRule = createAndroidComposeRule<ComposeFocusTestActivity>()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import androidx.test.espresso.matcher.ViewMatchers
import com.google.common.truth.Truth.assertThat
import com.rubensousa.dpadrecyclerview.DpadRecyclerView
import com.rubensousa.dpadrecyclerview.ExtraLayoutSpaceStrategy
import com.rubensousa.dpadrecyclerview.testfixtures.DefaultInstrumentedReportRule
import com.rubensousa.dpadrecyclerview.testfixtures.DpadFocusEvent
import com.rubensousa.dpadrecyclerview.testing.KeyEvents
import com.rubensousa.dpadrecyclerview.testing.R
Expand All @@ -42,9 +41,6 @@ import org.junit.Test

class DpadComposeFocusViewHolderTest {

@get:Rule(order = -1)
val report = DefaultInstrumentedReportRule()

@get:Rule
val composeTestRule = createAndroidComposeRule<ComposeFocusTestActivity>()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import androidx.test.espresso.matcher.ViewMatchers
import com.google.common.truth.Truth.assertThat
import com.rubensousa.dpadrecyclerview.DpadRecyclerView
import com.rubensousa.dpadrecyclerview.ExtraLayoutSpaceStrategy
import com.rubensousa.dpadrecyclerview.testfixtures.DefaultInstrumentedReportRule
import com.rubensousa.dpadrecyclerview.testfixtures.DpadFocusEvent
import com.rubensousa.dpadrecyclerview.testing.KeyEvents
import com.rubensousa.dpadrecyclerview.testing.R
Expand All @@ -39,9 +38,6 @@ import org.junit.Test

class DpadComposeViewHolderTest {

@get:Rule(order = -1)
val report = DefaultInstrumentedReportRule()

@get:Rule
val composeTestRule = createAndroidComposeRule<ViewFocusTestActivity>()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class DpadGridFragment : Fragment(R.layout.dpadrecyclerview_test_container),
}

override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class DpadVerticalFragment : Fragment(R.layout.dpadrecyclerview_test_container),
}

override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,12 @@ import androidx.test.espresso.ViewAssertion
import androidx.test.espresso.ViewInteraction
import androidx.test.espresso.matcher.ViewMatchers
import com.google.common.truth.Truth.assertThat
import com.rubensousa.dpadrecyclerview.testfixtures.DefaultInstrumentedReportRule
import com.rubensousa.dpadrecyclerview.testing.DpadGridFragment
import com.rubensousa.dpadrecyclerview.testing.DpadSubPositionFragment
import com.rubensousa.dpadrecyclerview.testing.R
import org.junit.Rule

abstract class RecyclerViewTest {

@get:Rule(order = -1)
val report = DefaultInstrumentedReportRule()

private lateinit var subPositionFragment: FragmentScenario<DpadSubPositionFragment>
private lateinit var gridFragment: FragmentScenario<DpadGridFragment>

Expand Down
14 changes: 7 additions & 7 deletions dpadrecyclerview/api/dpadrecyclerview.api
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ public final class com/rubensousa/dpadrecyclerview/FocusableDirection : java/lan
}

public abstract interface class com/rubensousa/dpadrecyclerview/OnChildLaidOutListener {
public abstract fun onChildLaidOut (Landroidx/recyclerview/widget/RecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;)V
public abstract fun onChildLaidOut (Lcom/rubensousa/dpadrecyclerview/DpadRecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;)V
}

public abstract interface class com/rubensousa/dpadrecyclerview/OnFocusLostListener {
Expand All @@ -348,15 +348,15 @@ public abstract interface class com/rubensousa/dpadrecyclerview/OnViewFocusedLis
}

public abstract interface class com/rubensousa/dpadrecyclerview/OnViewHolderSelectedListener {
public abstract fun onViewHolderDeselected (Landroidx/recyclerview/widget/RecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;)V
public abstract fun onViewHolderSelected (Landroidx/recyclerview/widget/RecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;II)V
public abstract fun onViewHolderSelectedAndAligned (Landroidx/recyclerview/widget/RecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;II)V
public abstract fun onViewHolderDeselected (Lcom/rubensousa/dpadrecyclerview/DpadRecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;)V
public abstract fun onViewHolderSelected (Lcom/rubensousa/dpadrecyclerview/DpadRecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;II)V
public abstract fun onViewHolderSelectedAndAligned (Lcom/rubensousa/dpadrecyclerview/DpadRecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;II)V
}

public final class com/rubensousa/dpadrecyclerview/OnViewHolderSelectedListener$DefaultImpls {
public static fun onViewHolderDeselected (Lcom/rubensousa/dpadrecyclerview/OnViewHolderSelectedListener;Landroidx/recyclerview/widget/RecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;)V
public static fun onViewHolderSelected (Lcom/rubensousa/dpadrecyclerview/OnViewHolderSelectedListener;Landroidx/recyclerview/widget/RecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;II)V
public static fun onViewHolderSelectedAndAligned (Lcom/rubensousa/dpadrecyclerview/OnViewHolderSelectedListener;Landroidx/recyclerview/widget/RecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;II)V
public static fun onViewHolderDeselected (Lcom/rubensousa/dpadrecyclerview/OnViewHolderSelectedListener;Lcom/rubensousa/dpadrecyclerview/DpadRecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;)V
public static fun onViewHolderSelected (Lcom/rubensousa/dpadrecyclerview/OnViewHolderSelectedListener;Lcom/rubensousa/dpadrecyclerview/DpadRecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;II)V
public static fun onViewHolderSelectedAndAligned (Lcom/rubensousa/dpadrecyclerview/OnViewHolderSelectedListener;Lcom/rubensousa/dpadrecyclerview/DpadRecyclerView;Landroidx/recyclerview/widget/RecyclerView$ViewHolder;II)V
}

public final class com/rubensousa/dpadrecyclerview/ParentAlignment : android/os/Parcelable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ open class TestGridFragment : Fragment(R.layout.dpadrecyclerview_test_container)
)
}

override fun onViewHolderDeselected(parent: RecyclerView, child: RecyclerView.ViewHolder) {
override fun onViewHolderDeselected(parent: DpadRecyclerView, child: RecyclerView.ViewHolder) {
deselectionEvents.add(DpadDeselectionEvent(child))
}

override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand All @@ -143,7 +143,7 @@ open class TestGridFragment : Fragment(R.layout.dpadrecyclerview_test_container)
}

override fun onViewHolderSelectedAndAligned(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down Expand Up @@ -218,7 +218,7 @@ open class TestGridFragment : Fragment(R.layout.dpadrecyclerview_test_container)
focusEvents.add(DpadFocusEvent(parent, child, parent.layoutPosition))
}

override fun onChildLaidOut(parent: RecyclerView, child: RecyclerView.ViewHolder) {
override fun onChildLaidOut(parent: DpadRecyclerView, child: RecyclerView.ViewHolder) {
layoutEvents.add(child)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class TestPaginationFragment : TestGridFragment() {
}

override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class LayoutCompletionTest : DpadRecyclerViewTest() {
repeat(listeners) {
currentRecyclerView!!.addOnChildLaidOutListener(object : OnChildLaidOutListener {
override fun onChildLaidOut(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder
) {
currentRecyclerView.removeOnChildLaidOutListener(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ class SelectionTest : DpadRecyclerViewTest() {
recyclerView.addOnViewHolderSelectedListener(object :
OnViewHolderSelectedListener {
override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ interface OnChildLaidOutListener {
* @param parent the [RecyclerView] that contains this child
* @param child the [RecyclerView.ViewHolder] that was laid out
*/
fun onChildLaidOut(parent: RecyclerView, child: RecyclerView.ViewHolder)
fun onChildLaidOut(parent: DpadRecyclerView, child: RecyclerView.ViewHolder)
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ interface OnViewHolderSelectedListener {
* or 0 if there is no custom alignment
*/
fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand All @@ -59,7 +59,7 @@ interface OnViewHolderSelectedListener {
* or 0 if there is no custom alignment
*/
fun onViewHolderSelectedAndAligned(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand All @@ -71,7 +71,7 @@ interface OnViewHolderSelectedListener {
* @param child The ViewHolder within the RecyclerView that was deselected
*/
fun onViewHolderDeselected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder,
) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ internal class ViewHolderTaskExecutor : OnViewHolderSelectedListener {
}

override fun onViewHolderSelected(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand All @@ -52,7 +52,7 @@ internal class ViewHolderTaskExecutor : OnViewHolderSelectedListener {
}

override fun onViewHolderSelectedAndAligned(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ internal class PivotSelector(
* Set to [OFFSET_DISABLED] means we should stop adding it to [position] until the next layout.
*/
private var positionOffset = 0
private var recyclerView: RecyclerView? = null
private var recyclerView: DpadRecyclerView? = null
private var isSelectionUpdatePending = false
private val selectionListeners = ArrayList<OnViewHolderSelectedListener>()
private val focusListeners = ArrayList<OnViewFocusedListener>()
Expand Down Expand Up @@ -444,7 +444,7 @@ internal class PivotSelector(
focusListeners.clear()
}

fun setRecyclerView(recyclerView: RecyclerView?) {
fun setRecyclerView(recyclerView: DpadRecyclerView?) {
this.recyclerView = recyclerView
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.recyclerview.widget.OrientationHelper
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.LayoutManager
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.rubensousa.dpadrecyclerview.DpadRecyclerView
import com.rubensousa.dpadrecyclerview.layoutmanager.DpadLayoutParams
import com.rubensousa.dpadrecyclerview.layoutmanager.LayoutConfiguration

Expand Down Expand Up @@ -66,7 +67,7 @@ internal class LayoutInfo(
var isLoopingStart = false
private set

private var recyclerView: RecyclerView? = null
private var recyclerView: DpadRecyclerView? = null

fun getConfiguration() = configuration

Expand All @@ -76,7 +77,7 @@ internal class LayoutInfo(

fun isVertical() = configuration.isVertical()

fun getRecyclerView(): RecyclerView? = recyclerView
fun getRecyclerView(): DpadRecyclerView? = recyclerView

fun updateOrientation() {
orientationHelper = OrientationHelper.createOrientationHelper(
Expand Down Expand Up @@ -113,7 +114,7 @@ internal class LayoutInfo(
this.isLoopingAllowed = isLoopingAllowed
}

fun setRecyclerView(recyclerView: RecyclerView?) {
fun setRecyclerView(recyclerView: DpadRecyclerView?) {
this.recyclerView = recyclerView
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class DpadScrollState internal constructor() {
private val states = mutableMapOf<String, Parcelable>()
private val selectionListener = object : OnViewHolderSelectedListener {
override fun onViewHolderSelectedAndAligned(
parent: RecyclerView,
parent: DpadRecyclerView,
child: RecyclerView.ViewHolder?,
position: Int,
subPosition: Int
Expand Down
Loading

0 comments on commit ca5a3d2

Please sign in to comment.