I wanna achieve the following be behavior for one screen of my app. I have a fragment's layout with ConstraintLayout as it's parent. Inside ConstraintLayout I have a ScrollView with nested ConstraintLayout (nested ConstraintLayout contains ImageView and TextView) and simple Button below the ScrollView.
I wanna enable button as soon as user reaches to the bottom of ScrollView and disable when user scrolls up.
Layout is below.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
>
<ScrollView
android:id="@+id/scrollableView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_constraintBottom_toTopOf="@id/elevationShadow"
app:layout_constraintTop_toBottomOf="@id/appbar">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_marginStart="@dimen/spacing_large"
android:layout_marginEnd="@dimen/spacing_large"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/user_image"
android:layout_width="144dp"
android:layout_height="144dp"
android:layout_gravity="center"
android:layout_marginTop="@dimen/spacing_large"
android:src="@drawable/user_image"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/text_size_xxlarge"
android:textStyle="bold"
android:textAlignment="center"
android:textColor="@color/black_color"
android:layout_marginTop="@dimen/spacing_large"
tools:text="Tools text"
android:textAppearance="?tvptTextAppearanceBody"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/user_image"
/>
<TextView
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/spacing_large"
android:textAlignment="center"
android:textSize="@dimen/user_info_content_text_size"
android:textAppearance="?tvptTextAppearanceBody"
android:textColor="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/heading"
tools:text="Tools test content"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<View
android:id="@+id/elevationShadow"
android:layout_width="match_parent"
android:layout_height="3dp"
android:background="@drawable/shadow_elevation"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginBottom="@dimen/user_info_activity_confirm_button_margin"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@id/button_confirm"/>
<com.travelportdigital.android.compasswidget.button.PercentageBasedStateButton
android:id="@+id/button_confirm"
style="@style/PrimaryButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:layout_marginBottom="@dimen/user_info_activity_confirm_button_margin"
android:text="@string/user_info_continueButton_title"
android:textAllCaps="true"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The problem is that content for TextView which is inside ScrollView can both long and short. That's why I had to add ScrollView if the content is long.
By the small piece of code I was able to achieve the behavior I needed with one small remark.
fun addScrollChangeListener() {
scrollView.viewTreeObserver
.addOnScrollChangedListener {
enableContinueButton(scrollView.getChildAt(0).bottom <= scrollView.height + scrollView.scrollY)
}
}
And the code above works fine for the scenario when content is long (when user arrives to this screen Continue button is disabled and when user scrolls to the bottom of the scroll view it become enabled if user scrolls up it becomes disabled again.
I wanna update this logic to enable button when user arrives to this screen and content of TextView inside ScrollView is short (no need scrolling for this scenario).
I made some researches in Google and could not find the solution which would work for me.
In onViewCreated() method I added logic to disable or enable button when user arrives to this screen.
enableContinueButton(!isScrollingRequired())
I tried this implementation
private fun isScrollingRequired(): Boolean {
val view = scrollView.getChildAt(scrollView.childCount - 1) as View
val diff = view.bottom - (scrollView.height + scrollView.scrollY)
return diff != 0
}
and this
return if (child != null) {
val childHeight = child.height
scrollView.height <= childHeight + scrollView.paddingTop + scrollView.paddingBottom;
} else {
false
}
but it did not work, because ScrollView height and it's child height is always 0
Looking forward your advices.
Regards, Alex