From e99a31fdd3336e638ae3444fccc81c7340c8f932 Mon Sep 17 00:00:00 2001 From: Ruben Sousa Date: Wed, 21 Aug 2024 18:51:51 +0200 Subject: [PATCH] Fix header not keeping the same anchor --- .../tests/layout/DpadScrollableLayoutTest.kt | 55 +++++++++++-------- .../dpadrecyclerview_scrollable_container.xml | 46 +++++++++------- .../dpadrecyclerview/DpadScrollableLayout.kt | 25 +++++++-- 3 files changed, 79 insertions(+), 47 deletions(-) diff --git a/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/layout/DpadScrollableLayoutTest.kt b/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/layout/DpadScrollableLayoutTest.kt index b5453ea3..e5b8146d 100644 --- a/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/layout/DpadScrollableLayoutTest.kt +++ b/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/layout/DpadScrollableLayoutTest.kt @@ -19,6 +19,7 @@ package com.rubensousa.dpadrecyclerview.test.tests.layout import android.graphics.Rect import android.os.Bundle import android.view.View +import android.view.ViewGroup import androidx.core.view.updateLayoutParams import androidx.fragment.app.Fragment import androidx.fragment.app.testing.FragmentScenario @@ -87,6 +88,23 @@ class DpadScrollableLayoutTest { ) } + @Test + fun testHeaderStartsCompletelyVisible() { + val headerBounds = getViewBounds(R.id.headerLayout) + assertThat(headerBounds.top).isEqualTo(0) + + var completelyVisible = false + var visible = false + + fragmentScenario.onFragment { fragment -> + completelyVisible = fragment.scrollableLayout!!.isHeaderCompletelyVisible + visible = fragment.scrollableLayout!!.isHeaderVisible + } + + assertThat(completelyVisible).isTrue() + assertThat(visible).isTrue() + } + @Test fun testHidingHeaderWithoutAnimation() { // given @@ -259,13 +277,13 @@ class DpadScrollableLayoutTest { // when fragmentScenario.onFragment { fragment -> - fragment.scrollableLayout?.removeViewAt(0) + fragment.scrollableLayout?.findViewById(R.id.headerLayout)?.removeViewAt(0) } // then - val header2Bounds = getViewBounds(R.id.header2) + val headerBounds = getViewBounds(R.id.headerLayout) val recyclerViewBounds = getViewBounds(R.id.recyclerView) - assertThat(header2Bounds).isEqualTo( + assertThat(headerBounds).isEqualTo( Rect(0, -headerHeight, screenWidth, 0) ) assertThat(recyclerViewBounds).isEqualTo( @@ -286,13 +304,13 @@ class DpadScrollableLayoutTest { // when fragmentScenario.onFragment { fragment -> - fragment.scrollableLayout?.removeViewAt(0) + fragment.scrollableLayout?.findViewById(R.id.headerLayout)?.removeViewAt(0) } // then - val header2Bounds = getViewBounds(R.id.header2) + val headerBounds = getViewBounds(R.id.headerLayout) val recyclerViewBounds = getViewBounds(R.id.recyclerView) - assertThat(header2Bounds).isEqualTo( + assertThat(headerBounds).isEqualTo( Rect(0, 0, screenWidth, headerHeight) ) assertThat(recyclerViewBounds).isEqualTo( @@ -313,7 +331,7 @@ class DpadScrollableLayoutTest { // when fragmentScenario.onFragment { fragment -> - fragment.header1?.updateLayoutParams { + fragment.header1?.updateLayoutParams { height *= 2 } } @@ -334,36 +352,25 @@ class DpadScrollableLayoutTest { } @Test - fun testOffsetIsAdjustedWhenLayoutGetsBiggerWhileHeaderIsVisible() { + fun testBottomStaysAlignedWhenHeaderGrowsWhileVisible() { // given val headerHeight = getHeaderHeight() - val screenWidth = getWidth() - val screenHeight = getHeight() fragmentScenario.onFragment { fragment -> fragment.scrollableLayout?.scrollHeaderTo(topOffset = -headerHeight / 2) } waitViewAtCoordinates(R.id.header1, top = -headerHeight / 2, bottom = headerHeight / 2) + val headerBounds = getViewBounds(R.id.headerLayout) // when fragmentScenario.onFragment { fragment -> - fragment.header1?.updateLayoutParams { + fragment.header1?.updateLayoutParams { height *= 2 } } // then - val header1Bounds = getViewBounds(R.id.header1) - val header2Bounds = getViewBounds(R.id.header2) - val recyclerViewBounds = getViewBounds(R.id.recyclerView) - assertThat(header1Bounds).isEqualTo( - Rect(0, 0, screenWidth, headerHeight * 2) - ) - assertThat(header2Bounds).isEqualTo( - Rect(0, headerHeight * 2, screenWidth, headerHeight * 3) - ) - assertThat(recyclerViewBounds).isEqualTo( - Rect(0, headerHeight * 3, screenWidth, screenHeight + headerHeight * 3) - ) + val newBounds = getViewBounds(R.id.headerLayout) + assertThat(newBounds.bottom).isEqualTo(headerBounds.bottom) } @Test @@ -384,7 +391,7 @@ class DpadScrollableLayoutTest { // then val header1Bounds = getViewBounds(R.id.header1) assertThat(header1Bounds).isEqualTo( - Rect(0, -headerHeight / 2, screenWidth, headerHeight / 2) + Rect(0, -headerHeight / 2, screenWidth, headerHeight / 2) ) } diff --git a/dpadrecyclerview/src/androidTest/res/layout/dpadrecyclerview_scrollable_container.xml b/dpadrecyclerview/src/androidTest/res/layout/dpadrecyclerview_scrollable_container.xml index 490eddac..9cd3a381 100644 --- a/dpadrecyclerview/src/androidTest/res/layout/dpadrecyclerview_scrollable_container.xml +++ b/dpadrecyclerview/src/androidTest/res/layout/dpadrecyclerview_scrollable_container.xml @@ -5,27 +5,35 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="wrap_content" + android:orientation="vertical"> - + + + + + -headerHeight + isHeaderCompletelyVisible = currentOffset == 0 } private fun cancelOffsetAnimation() {