Christer Nordvik
Christer Nordvik

Reputation: 2528

Animate content up when hiding actionbar/toolbar

I have used the code in the Google IO repo: https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java

I am trying to hide the toolbar when scrolling up and it works great, but my problem is that my main content stays fixed in place when the toolbar animates out of screen.

The code that runs the animation on the R.id.toolbar_actionbar is:

view.animate()
        .translationY(-view.getBottom())
        .alpha(0)
        .setDuration(HEADER_HIDE_ANIM_DURATION)
        .setInterpolator(new DecelerateInterpolator());

I have tried putting the toolbar inside a linearlayout with the content but it didn't change anything. Only if I set the actionbar to visibility=gone will the content move up.

Does anyone know what I must do to make the content animate together with the translate animation of the toolbar?

Basically the question boils down to: How can I animate the position of one view and make the other views animate with it?

The Google IO code seems to just animate the toolbar and the rest of the content animates with it but I cannot get that to work.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <include
        android:id="@+id/toolbar_actionbar"
        layout="@layout/toolbar_actionbar" />

    <FrameLayout
        android:id="@+id/main_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/adsContainer"
        android:layout_below="@+id/toolbar_actionbar" />

    <LinearLayout
        android:id="@+id/adsContainer"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="#000000"
        android:orientation="horizontal" />
</RelativeLayout>
<!-- The navigation drawer -->

<ExpandableListView
    android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="#111"
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"
    android:dividerHeight="0dp" />

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

Upvotes: 3

Views: 8159

Answers (2)

Sumit
Sumit

Reputation: 55

I also had the same problem of Content staying where it was even after the actionbar (appcompat v7 toolbar widget) slides up when the list view is scrolled up.

Followed Christer's layout for the activity's layout.

This may be dirty fix or may be I messed my layouts. But still posting here to get better solutions. So here it is:

My Content (fragment layout) root element was like this:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_content_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="?attr/actionBarSize" >
............

And my activity layout looked like this:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <include
        android:id="@+id/toolbar_actionbar"
        layout="@layout/action_bar" />
</RelativeLayout>
.........other stuff.........

The dirty fix was to introduce a fake toolbar in the Fragment layout and keep it on the top.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_content_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

<View
    android:id="@+id/fakeToolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:layout_alignParentTop="true" />

.............Other elements like ListView/GridView below this........ 

And the in onscroll methods make the fakeToolbar visible/invisible along with the actual ToolBar sliding up/down:

    mToolbar.animate().translationY(0).alpha(1)
            .setDuration(HEADER_HIDE_ANIM_DURATION)
            .setInterpolator(new DecelerateInterpolator()).withStartAction(new Runnable() {

                @Override
                public void run() {
                    fakeToolbar.setVisibility(View.VISIBLE);                        
                }
            });     

This fix gave a smooth transition to the layout while scrolling.

Upvotes: 1

Simas
Simas

Reputation: 44128

You can use this little snippet to animate a view's height:

public void animateHeight(final View view, int from, int to, int duration) {
    ValueAnimator anim = ValueAnimator.ofInt(from, to);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            int val = (Integer) valueAnimator.getAnimatedValue();
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            layoutParams.height = val;
            view.setLayoutParams(layoutParams);
        }
    });
    anim.setDuration(duration);
    anim.start();
}

Calling it would look something like this:

View view = findViewById(R.id.view);
// Wait for layout to be drawn before measuring it
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View view, int i, int i2, int i3, int i4, int i5, int i6, int i7, int i8) {
        view.removeOnLayoutChangeListener(this);
        animateHeight(view, view.getHeight(), 0, 5000);
    }
});

Upvotes: 7

Related Questions