Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impose layout size as limit for scrolling when there is an AlignmentLookup set #270

Merged
merged 6 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ jobs:
ram-size: 4096M
emulator-options: -no-window -no-snapshot-save -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
script: |
./gradlew uninstallAll
./scripts/uninstall_test_services.sh
adb shell settings put global verifier_verify_adb_installs 0
./gradlew --build-cache dpadrecyclerview-compose:connectedDebugAndroidTest
./gradlew --build-cache sample:connectedDebugAndroidTest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:
ram-size: 4096M
emulator-options: -no-window -no-snapshot-save -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
script: |
./scripts/install_test_apks.sh
./scripts/uninstall_test_services.sh

- name: Upload artifacts
uses: actions/upload-artifact@v3
Expand Down
Binary file removed artifacts/orchestrator-1.4.2.apk
Binary file not shown.
Binary file removed artifacts/test-services-1.4.2.apk
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ class AlignmentLookupTest : DpadRecyclerViewTest() {
val recyclerViewBounds = getRecyclerViewBounds()

onRecyclerView("Set alignment") { recyclerView ->
recyclerView.setSmoothScrollMaxPendingMoves(1)
recyclerView.setAlignmentLookup(object : AlignmentLookup {
override fun getParentAlignment(
viewHolder: RecyclerView.ViewHolder,
Expand Down Expand Up @@ -187,4 +186,49 @@ class AlignmentLookupTest : DpadRecyclerViewTest() {
assertThat(viewBounds.bottom).isEqualTo(recyclerViewBounds.bottom)
}

@Test
fun testAlignmentLookupSmoothScrolling() = report {
Given("Launch Fragment with top alignment") {
launchFragment()
}

var scrolled = false
When("Set AlignmentLookup for 50% of screen height") {
onRecyclerView("Set alignment") { recyclerView ->
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState != RecyclerView.SCROLL_STATE_IDLE) {
scrolled = true
}
}
})
recyclerView.setAlignmentLookup(
object : AlignmentLookup {
override fun getParentAlignment(
viewHolder: RecyclerView.ViewHolder,
): ParentAlignment {
return ParentAlignment(fraction = 0.5f)
}

override fun getChildAlignment(
viewHolder: RecyclerView.ViewHolder,
): ChildAlignment {
return ChildAlignment(fraction = 0.5f)
}
},
smooth = true
)
}
}

Then("RecyclerView scrolled to new position") {
waitForIdleScrollState()
val recyclerViewBounds = getRecyclerViewBounds()
val viewBounds = getItemViewBounds(position = 0)
assertThat(scrolled).isTrue()
assertThat(viewBounds.centerY()).isEqualTo(recyclerViewBounds.height() / 2)
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
import com.rubensousa.carioca.report.android.recording.TestRecording
import com.rubensousa.dpadrecyclerview.ChildAlignment
import com.rubensousa.dpadrecyclerview.ParentAlignment
import com.rubensousa.dpadrecyclerview.layoutmanager.layout.ViewBounds
Expand Down Expand Up @@ -270,6 +271,7 @@ class AdapterMutationTest : DpadRecyclerViewTest() {

}

@TestRecording(keepOnSuccess = true)
@Test
fun testRemovalOfLargeInterval() {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,13 @@ class PivotLayoutManager(properties: Properties) : RecyclerView.LayoutManager(),
override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
// If we have focus, save it temporarily since the views will change and we might lose it
hadFocusBeforeLayout = hasFocus()
if (layoutInfo.isScrollingToTarget) {
scroller.cancelScrollToTarget()
}
pivotLayout.onLayoutChildren(recycler, state)
if (hadFocusBeforeLayout) {
focusDispatcher.focusSelectedView()
}
if (layoutInfo.isScrollingToTarget) {
scroller.cancelScrollToTarget()
}
hadFocusBeforeLayout = false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,6 @@ internal class LayoutAlignment(
if (itemCount == 0) {
return
}
/**
* Client wants to specify the alignments manually,
* so we shouldn't impose any scroll limits
*/
if (alignmentLookup != null) {
parentAlignmentCalculator.invalidateScrollLimits()
return
}
val endAdapterPos: Int
val startAdapterPos: Int
val endLayoutPos: Int
Expand Down Expand Up @@ -281,6 +273,19 @@ internal class LayoutAlignment(
startEdge = Int.MIN_VALUE
startViewAnchor = Int.MIN_VALUE
}
/**
* Client wants to specify the alignments manually,
* so we should impose different scroll limits
*/
if (alignmentLookup != null) {
parentAlignmentCalculator.setScrollStartLimit(
limit = -layoutManager.height
)
parentAlignmentCalculator.setScrollEndLimit(
limit = layoutManager.height
)
return
}
if (!reverseLayout) {
parentAlignmentCalculator.updateScrollLimits(
startEdge = startEdge,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ internal class ParentAlignmentCalculator {
private var endEdge = Int.MAX_VALUE
private var startEdge = Int.MIN_VALUE

fun setScrollStartLimit(limit: Int) {
startScrollLimit = limit
}

fun setScrollEndLimit(limit: Int) {
endScrollLimit = limit
}

fun updateLayoutInfo(
layoutManager: LayoutManager,
isVertical: Boolean,
Expand Down
9 changes: 0 additions & 9 deletions scripts/install_test_apks.sh

This file was deleted.

5 changes: 5 additions & 0 deletions scripts/uninstall_test_services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
adb uninstall androidx.test.orchestrator 2> /dev/null
adb uninstall androidx.test.services 2> /dev/null
./gradlew uninstalAll || exit 1
exit 0
Loading