Search code examples
androidkotlinandroid-recyclerviewfloating-action-buttonrecyclerview-layout

How do I show my fab on scroll when the first item in the recycler view is not visible but hide when the first item is visible?


So I am trying to implement a FAB button such that, when I scroll my recycler view and the first item is not visible (scrolled up etc) , fab button should be visible, else it should be hidden if the first position is showing. Right now I have implemented the code, but it doesn't show the fab button at all, just wanted to know what I am doing wrong?

my xml code is below:

<Linearlayout ....


    <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        <android.support.v4.widget.SwipeRefreshLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/pullToRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/myRecyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </android.support.v4.widget.SwipeRefreshLayout>

            <android.support.design.widget.FloatingActionButton
                android:id="@+id/emailFab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_margin="16dp"
                android:src="@android:drawable/ic_dialog_email"
                app:layout_anchor="@id/myRecyclerView"
                android:layout_gravity="bottom|end"
                app:layout_behavior="com.example.fab.ScrollAwareFABBehavior"
                app:layout_anchorGravity="bottom|end"
                />
        </FrameLayout>

</LinearLayout>

my Kotlin code is below:

val positionView = (myRecyclerView.getLayoutManager() as LinearLayoutManager).findFirstVisibleItemPosition()

myRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                if (dy >0 && positionView > 0) {
                    emailFab.show();
                } else  {
                    emailFab.hide();
                }
            }

Any ideas how to go about it?

Thanks!


Solution

  • I think the problem is that you should pull the findFirstVisibleItemPosition() into the OnScrollListener to find visible position in scroll changes:

    myRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
    
                val positionView = (myRecyclerView.getLayoutManager() as LinearLayoutManager).findFirstVisibleItemPosition()
    
                if (positionView > 0) {
                    if(!emailFab.isShown) {
                        emailFab.show();
                    }
                } else  {
                    if(emailFab.isShown) {
                        emailFab.hide();
                    }
                }
            }
        })