diff --git a/docs/changelog.md b/docs/changelog.md index 6413faf5..c78444e3 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -2,6 +2,14 @@ ## Version 1.1.0 +### 1.1.0-beta02 + +2023-09-15 + +#### Bug fixes + +- Fixed wrong scrolling behavior when the `app:spanCount` attribute is used for grids ([#162](https://github.com/rubensousa/DpadRecyclerView/issues/162)) + ### 1.1.0-beta01 2023-09-10 diff --git a/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManagerTest.kt b/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManagerTest.kt new file mode 100644 index 00000000..fb1d7f5b --- /dev/null +++ b/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManagerTest.kt @@ -0,0 +1,17 @@ +package com.rubensousa.dpadrecyclerview.layoutmanager + +import androidx.recyclerview.widget.RecyclerView.LayoutManager.Properties +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +class PivotLayoutManagerTest { + + @Test + fun testDefaultSpanCountIsSetThroughConstructor() { + val properties = Properties() + properties.spanCount = 5 + val pivotLayoutManager = PivotLayoutManager(properties) + assertThat(pivotLayoutManager.getSpanCount()).isEqualTo(properties.spanCount) + } + +} diff --git a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManager.kt b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManager.kt index 4a673192..e94694ba 100644 --- a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManager.kt +++ b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManager.kt @@ -23,6 +23,7 @@ import android.os.Parcelable import android.util.AttributeSet import android.view.View import android.view.ViewGroup +import androidx.annotation.VisibleForTesting import androidx.core.view.accessibility.AccessibilityNodeInfoCompat import androidx.recyclerview.widget.RecyclerView import com.rubensousa.dpadrecyclerview.ChildAlignment @@ -53,7 +54,7 @@ class PivotLayoutManager(properties: Properties) : RecyclerView.LayoutManager() private val layoutInfo = LayoutInfo(this, configuration) private val pivotSelector = PivotSelector(this, layoutInfo) private val layoutAlignment = LayoutAlignment(this, layoutInfo) - private val spanFocusFinder = SpanFocusFinder() + private val spanFocusFinder = SpanFocusFinder(configuration) private val scroller = LayoutScroller( this, layoutInfo, layoutAlignment, configuration, pivotSelector, spanFocusFinder ) @@ -396,7 +397,7 @@ class PivotLayoutManager(properties: Properties) : RecyclerView.LayoutManager() fun setSpanCount(spanCount: Int) { if (configuration.spanCount != spanCount) { configuration.setSpanCount(spanCount) - spanFocusFinder.setSpanCount(spanCount) + spanFocusFinder.clearSpanCache() pivotLayout.updateStructure() requestLayout() } @@ -407,7 +408,7 @@ class PivotLayoutManager(properties: Properties) : RecyclerView.LayoutManager() fun setSpanSizeLookup(spanSizeLookup: DpadSpanSizeLookup) { if (spanSizeLookup !== configuration.spanSizeLookup) { configuration.setSpanSizeLookup(spanSizeLookup) - spanFocusFinder.setSpanCount(configuration.spanCount) + spanFocusFinder.clearSpanCache() requestLayout() } } @@ -570,4 +571,9 @@ class PivotLayoutManager(properties: Properties) : RecyclerView.LayoutManager() } } + @VisibleForTesting + internal fun getFocusFinderSpanCount(): Int { + return spanFocusFinder.spanCount + } + } diff --git a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/focus/SpanFocusFinder.kt b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/focus/SpanFocusFinder.kt index 59917117..0ed3e737 100644 --- a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/focus/SpanFocusFinder.kt +++ b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/focus/SpanFocusFinder.kt @@ -18,18 +18,20 @@ package com.rubensousa.dpadrecyclerview.layoutmanager.focus import androidx.recyclerview.widget.RecyclerView import com.rubensousa.dpadrecyclerview.DpadSpanSizeLookup +import com.rubensousa.dpadrecyclerview.layoutmanager.LayoutConfiguration /** * Holds information about the previous focused spanIndex on all spanGroups */ -internal class SpanFocusFinder { +internal class SpanFocusFinder(private val configuration: LayoutConfiguration) { + + val spanCount: Int + get() = configuration.spanCount - private var spanCount = 1 private var cachedSpanIndex = RecyclerView.NO_POSITION private var cachedSpanSize = 1 - fun setSpanCount(newSpanCount: Int) { - spanCount = newSpanCount + fun clearSpanCache() { cachedSpanIndex = RecyclerView.NO_POSITION cachedSpanSize = 1 } diff --git a/dpadrecyclerview/src/test/java/com/rubensousa/dpadrecyclerview/test/layoutmanager/focus/SpanFocusFinderTest.kt b/dpadrecyclerview/src/test/java/com/rubensousa/dpadrecyclerview/test/layoutmanager/focus/SpanFocusFinderTest.kt index ede7aeb3..db952973 100644 --- a/dpadrecyclerview/src/test/java/com/rubensousa/dpadrecyclerview/test/layoutmanager/focus/SpanFocusFinderTest.kt +++ b/dpadrecyclerview/src/test/java/com/rubensousa/dpadrecyclerview/test/layoutmanager/focus/SpanFocusFinderTest.kt @@ -19,6 +19,7 @@ package com.rubensousa.dpadrecyclerview.test.layoutmanager.focus import androidx.recyclerview.widget.RecyclerView import com.google.common.truth.Truth.assertThat import com.rubensousa.dpadrecyclerview.DpadSpanSizeLookup +import com.rubensousa.dpadrecyclerview.layoutmanager.LayoutConfiguration import com.rubensousa.dpadrecyclerview.layoutmanager.focus.SpanFocusFinder import org.junit.Before import org.junit.Test @@ -26,13 +27,17 @@ import org.junit.Test class SpanFocusFinderTest { private val itemCount = 1000 - private var spanCount = 5 - private val finder = SpanFocusFinder() + private val configuration = LayoutConfiguration(RecyclerView.LayoutManager.Properties().apply { + spanCount = 5 + }) + private val spanCount: Int + get() = configuration.spanCount + private val finder = SpanFocusFinder(configuration) private val headerPosition = 0 private val headerSpanSizeLookup = object : DpadSpanSizeLookup() { override fun getSpanSize(position: Int): Int { return if (position == headerPosition) { - spanCount + configuration.spanCount } else { 1 } @@ -40,18 +45,18 @@ class SpanFocusFinderTest { } private val multipleHeadersLookup = object : DpadSpanSizeLookup() { override fun getSpanSize(position: Int): Int { - return if (position.rem(spanCount + 1) == 0 || position == 0) { - spanCount + return if (position.rem(configuration.spanCount + 1) == 0 || position == 0) { + configuration.spanCount } else { 1 } } } - private val secondHeaderPosition = spanCount + 1 + private val secondHeaderPosition = configuration.spanCount + 1 @Before fun setup() { - finder.setSpanCount(newSpanCount = spanCount) + finder.clearSpanCache() } @Test @@ -357,10 +362,10 @@ class SpanFocusFinderTest { @Test fun `finding next position does not query span size out of bounds`() { - spanCount = 3 - finder.setSpanCount(spanCount) + configuration.setSpanCount(3) + finder.clearSpanCache() val spanSizeQueries = mutableSetOf() - val spanSizeLookup = object: DpadSpanSizeLookup() { + val spanSizeLookup = object : DpadSpanSizeLookup() { override fun getSpanSize(position: Int): Int { spanSizeQueries.add(position) return 1 @@ -383,10 +388,10 @@ class SpanFocusFinderTest { @Test fun `finding previous position does not query span size out of bounds`() { - spanCount = 3 - finder.setSpanCount(spanCount) + configuration.setSpanCount(3) + finder.clearSpanCache() val spanSizeQueries = mutableSetOf() - val spanSizeLookup = object: DpadSpanSizeLookup() { + val spanSizeLookup = object : DpadSpanSizeLookup() { override fun getSpanSize(position: Int): Int { spanSizeQueries.add(position) return 1 @@ -407,5 +412,10 @@ class SpanFocusFinderTest { assertThat(spanSizeQueries).contains(0) } + @Test + fun `span count is derived from the layout configuration`() { + configuration.setSpanCount(10) + assertThat(finder.spanCount).isEqualTo(10) + } } diff --git a/gradle.properties b/gradle.properties index 32744afa..6d628f06 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,4 +22,4 @@ kotlin.code.style=official # thereby reducing the size of the R class for that library android.nonTransitiveRClass=true android.enableR8.fullMode=true -LIBRARY_VERSION=1.1.0-beta01 \ No newline at end of file +LIBRARY_VERSION=1.1.0-beta02 \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 0004ef3d..0db391ff 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -24,7 +24,7 @@ theme: extra: dpadrecyclerview: - version: '1.1.0-alpha03' + version: '1.1.0-beta02' social: - icon: 'fontawesome/brands/github' link: 'https://github.com/rubensousa/DpadRecyclerView'