Android change view visibility based on scroll position

Viewed 104

heads up: this is a long post

I am using a scroll view with a constraint layout inside it. and I have a view (say card view and a text inside it) let's call it toggleView and it's visible by default.

I want to hide the toggleView (set its visibility to View.INVISABLE) when the user scrolls down to the bottom of the screen. and when the user scrolls up I want to show it (set its visibility to View.VISIBLE).

the XML is similar to this:

 <ScrollView
        android:id="@+id/scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/image"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="16dp"
                android:layout_marginTop="16dp"
                android:layout_marginEnd="16dp"
                android:adjustViewBounds="true"
                android:contentDescription="@string/testString"
                android:scaleType="fitCenter"
                android:src="@drawable/testImage"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <TextView
                android:id="@+id/textView"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_below="@id/image"
                android:layout_marginTop="16dp"
                android:text="@string/textViewString"
                app:layout_constraintEnd_toEndOf="image"
                app:layout_constraintStart_toStartOf="image"
                app:layout_constraintTop_toBottomOf="@image" />
           
    <androidx.cardview.widget.CardView
        android:visibility="visible"
        android:id="@+id/toggleView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="textView"
        app:cardElevation="16dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="16dp"
            android:text="@string/toggleString" />
</androidx.cardview.widget.CardView>
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>


and this is the code that I use inside the fragment

 override fun onResume() {
// this is used to change the visiblity when the user scrolls the screen
binding.scrollview.setOnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
            val view = binding.scrollview.getChildAt(binding.scrollview.childCount - 1)
            val diff = view.bottom - (binding.scrollview.height + binding.scrollview.scrollY)

            if (diff <= toggleView.height) {
                toggleView.visibility = View.INVISIBLE
            } else {
                toggleView.visibility = View.VISIBLE
            }
        }
// this is used to change the state when the user first open the screen
 if (shouldHide(binding.scrollview, binding.toggleView)){
            binding.toggleView.visibility = View.INVISIBLE
        }else{
            binding.toggleView.visibility = View.VISIBLE
        }
   }
}
 fun shouldHide(scrollView: ScrollView, toggleView: CardView): Boolean {
        val view = scrollView.getChildAt(scrollView.childCount - 1)
        val diff = view.bottom - (scrollView.height + scrollView.scrollY)
        return diff <= toggleView.height
    }

this works just fine, but when I press the back button to go back to the previous fragment and then open this fragment again 3 times (it's always that number) and the fragment is visible again the toggle view is always visible.

what is the problem here?

0 Answers
Related