Hiding the ActionBar on RecyclerView/ListView onScroll

Graykos picture Graykos · Nov 26, 2012 · Viewed 50.4k times · Source

In my application I got an activity with some kind of actionbar at the top and the listview below it. What I want to do - is to scroll it UP with the list, so it hides and then, when the list is being scrolled down - it should scroll down with the list, like it was just over the upper screen border. how can i achieve this functionality?

Answer

Jared Burrows picture Jared Burrows · Jul 21, 2013

Updated 6/3/2015:

Google now supports this using the CoordinatorLayout.

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_done" />

</android.support.design.widget.CoordinatorLayout>

Source: https://github.com/chrisbanes/cheesesquare/blob/master/app/src/main/res/layout/include_list_viewpager.xml

Documented here: https://developer.android.com/reference/android/support/design/widget/AppBarLayout.html

Original Answer:

Example similar to Google Play Music and Umano apps:

https://github.com/umano/AndroidSlidingUpPanel

Take a look at the code in this repository. As you slide the panel up, the ActionBar slides up as well.

From the Demo:

   getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);

   SlidingUpPanelLayout layout = (SlidingUpPanelLayout) findViewById(R.id.sliding_layout);
    layout.setShadowDrawable(getResources().getDrawable(R.drawable.above_shadow));
    layout.setAnchorPoint(0.3f);
    layout.setPanelSlideListener(new PanelSlideListener() {
        @Override
        public void onPanelSlide(View panel, float slideOffset) {
            Log.i(TAG, "onPanelSlide, offset " + slideOffset);
            if (slideOffset < 0.2) {
                if (getActionBar().isShowing()) {
                    getActionBar().hide();
                }
            } else {
                if (!getActionBar().isShowing()) {
                    getActionBar().show();
                }
            }
        }

        @Override
        public void onPanelExpanded(View panel) {
            Log.i(TAG, "onPanelExpanded");

        }

        @Override
        public void onPanelCollapsed(View panel) {
            Log.i(TAG, "onPanelCollapsed");

        }

        @Override
        public void onPanelAnchored(View panel) {
            Log.i(TAG, "onPanelAnchored");

        }
    });

Download example here:

https://play.google.com/store/apps/details?id=com.sothree.umano

enter image description here

ListView - without Libraries:

I recently wanted the same functionality and this works perfectly for me:

As the user scrolls upward, the ActionBar will be hidden in order to give the user the entire screen to work work with.

As the user scrolls downward and lets go, the ActionBar will return.

getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);

listView.setOnScrollListener(new OnScrollListener() {
    int mLastFirstVisibleItem = 0;

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {   }           

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {    
        if (view.getId() == listView.getId()) {
            final int currentFirstVisibleItem = listView.getFirstVisiblePosition();

            if (currentFirstVisibleItem > mLastFirstVisibleItem) {
                // getSherlockActivity().getSupportActionBar().hide();
                getSupportActionBar().hide();
            } else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
                // getSherlockActivity().getSupportActionBar().show();
                getSupportActionBar().show();
            }

            mLastFirstVisibleItem = currentFirstVisibleItem;
        }               
    }
});

RecyclerView - without libraries

    this.mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
        int mLastFirstVisibleItem = 0;

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            final int currentFirstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();

            if (currentFirstVisibleItem > this.mLastFirstVisibleItem) {
                MainActivity.this.getSupportActionBar().hide();
            } else if (currentFirstVisibleItem < this.mLastFirstVisibleItem) {
                MainActivity.this.getSupportActionBar().show();
            }

            this.mLastFirstVisibleItem = currentFirstVisibleItem;
        }
    });

Let me know if you need anymore help!