1

I want to hide ActionBar when scrolling on my RecyclerView. To do that I'm using the quick return pattern.

Here is my styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->

    <item name="android:windowActionBarOverlay">true</item>
    <!-- Support library compatibility -->
    <item name="windowActionBarOverlay">true</item>
</style>

Here is my layout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipe_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include layout="@layout/recyclerview"/>

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

    <include layout="@layout/empty_layout"/>

    <fragment
        android:id="@+id/adFragment"
        android:name="com.myapp.fragment.AdFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" />

</RelativeLayout>

Here is my code to show/hide actionbar

@Override
public void onUpOrCancelMotionEvent(ScrollState scrollState) {
    ActionBar ab = ((ActionBarActivity)getActivity()).getSupportActionBar();
    boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
    if (!tabletSize) {
        if (scrollState == ScrollState.UP) {
            if (ab.isShowing()) {
                ab.hide();
            }
        } else if (scrollState == ScrollState.DOWN) {
            if (!ab.isShowing()) {
                ab.show();
            }
        }
    }
}

I'm using ?attr/actionBarSize to avoid flickering. But when ActionBar is hiding I'm still having the paddingTop.

enter image description here

How can I remove this paddingTop on the right screen when ActionBar is hidden ?

Cœur
  • 37,241
  • 25
  • 195
  • 267
guillaume
  • 1,638
  • 5
  • 24
  • 43

1 Answers1

2

Just use this listener in your ListView:

AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {

        int mLastFirstVisibleItem = 0;

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

        @Override
        public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount,
                             int totalItemCount) {


            final int lastItem = firstVisibleItem + visibleItemCount;

            if (absListView.getId() == wallListView.getId()) {

                final int currentFirstVisibleItem = wallListView.getFirstVisiblePosition();
                if (currentFirstVisibleItem > mLastFirstVisibleItem) {
                    actionBar.hide();
                } else if (currentFirstVisibleItem < mLastFirstVisibleItem) {
                    actionBar.show();
                }

                mLastFirstVisibleItem = currentFirstVisibleItem;
            }
        }

    };

If you would have the black area at top you must:

Add this code in your Activity

requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); //ADD THIS BEFORE setContentView(...);
setContentView(R.layout.your_layout);

Now will be good, but also u need to set the space of size which is equals size of ActionBar. We add Header to your ListView :

        View padding = new View(getApplicationContext());
        padding.setBackgroundColor(Color.TRANSPARENT);
        padding.setHeight(action_bar_size);
        your_list_view.addHeaderView(padding);

Or you can just set padding to ListView in XML, but this is bad, because the space will be cutted when ActionBar will be hiden.

If you want to add offset to SwipeRefreshLayout, try to use:

public void setProgressViewOffset (boolean scale, int start, int end)

The refresh indicator starting and resting position is always positioned near the top of the refreshing content. This position is a consistent location, but can be adjusted in either direction based on whether or not there is a toolbar or actionbar present.

Parameters scale Set to true if there is no view at a higher z-order than where the progress spinner is set to appear. start The offset in pixels from the top of this view at which the progress spinner should appear. end The offset in pixels from the top of this view at which the progress spinner should come to rest after a successful swipe gesture.

This must help you.

GIGAMOLE
  • 1,274
  • 1
  • 11
  • 17
  • I already have implemented the show/hidde but when the ActionBar is hidding there is a blank space as you can see on right screenshot. And I want to remove this blank space when the actionbar is hidden – guillaume Feb 04 '15 at 11:48
  • I had this idea too but as I'm using SwipeRefreshLayout, when I pull to refresh, the refresh animation is hidden. Is there a way to add paddingTop to this animation ? – guillaume Feb 04 '15 at 12:12
  • Ouuu. I had a similar problem. – GIGAMOLE Feb 04 '15 at 12:15
  • The setProgressViewOffset do the job ! Combined with http://stackoverflow.com/questions/26858692/swiperefreshlayout-setrefreshing-not-showing-indicator-initially I'm able to set the offset to actionbar height. thanks – guillaume Feb 04 '15 at 12:32