android - How to animate both top and bottom Toolbars(or any other view) enter/exit screen on scroll in CoordinatorLayout? -


my activity contains 2 appbarlayouts in coordinatorlayout, 1 on top of screen, , other bottom. want make both of 2 appbarlayouts hide on scroll of recyclerview.

when there top one, it's easy make hide on scroll adding app:layout_scrollflags="scroll|enteralways" toolbar, , app:layout_behavior="@string/appbar_scrolling_view_behavior" container of recyclerview.

when there bottom appbarlayout hide on scroll, realized making custom behavior bottomappbarlayoutbehavior extends appbarlayout.behavior.

however, when both of them made hide on scroll, succeed hide recyclerview shakes on scroll. , area of top toolbar leaves empty white space after hiding. below xml:

<android.support.design.widget.coordinatorlayout     android:layout_width="match_parent"     android:layout_height="match_parent"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:android="http://schemas.android.com/apk/res/android">      <android.support.design.widget.appbarlayout         android:layout_width="match_parent"         android:layout_height="wrap_content">          <android.support.v7.widget.toolbar             android:id="@+id/toptoolbar"             android:layout_width="fill_parent"             android:layout_height="wrap_content"             app:layout_scrollflags="scroll|enteralways" />      </android.support.design.widget.appbarlayout>      <framelayout         android:layout_width="fill_parent"         android:orientation="vertical"         app:layout_behavior="@string/appbar_scrolling_view_behavior"         android:id="@+id/recyclerviewcontainer"         android:layout_height="fill_parent"/>      <android.support.design.widget.appbarlayout          android:layout_width="match_parent"         android:layout_gravity="bottom"         app:layout_behavior="mypackage.bottomappbarlayoutbehavior">          <linearlayout             android:layout_width="match_parent"             android:orientation="horizontal"             android:layout_height="match_parent">             <!-- views -->         </linearlayout>      </android.support.design.widget.appbarlayout>  </android.support.design.widget.coordinatorlayout> 

below code of bottomappbarlayoutbehavior:

public class bottomappbarlayoutbehavior extends appbarlayout.behavior {     private static final interpolator interpolator = new fastoutslowininterpolator();     private boolean misanimatingout = false;      public bottomappbarlayoutbehavior(context context, attributeset attrs) {         super();     }      @override     public boolean onstartnestedscroll(final coordinatorlayout coordinatorlayout, final appbarlayout child,                                        final view directtargetchild, final view target, final int nestedscrollaxes) {         return nestedscrollaxes == viewcompat.scroll_axis_vertical                 || super.onstartnestedscroll(coordinatorlayout, child, directtargetchild, target, nestedscrollaxes);     }      @override     public void onnestedscroll(final coordinatorlayout coordinatorlayout, final appbarlayout child,                                final view target, final int dxconsumed, final int dyconsumed,                                final int dxunconsumed, final int dyunconsumed) {         super.onnestedscroll(coordinatorlayout, child, target, dxconsumed, dyconsumed, dxunconsumed, dyunconsumed);         if (dyconsumed > 0 && !this.misanimatingout && child.getvisibility() == view.visible) {             animateout(child);         } else if (dyconsumed < 0 && child.getvisibility() != view.visible) {             animatein(child);         }     }      private void animateout(final appbarlayout appbarlayout) {         if (build.version.sdk_int >= 14) {             viewcompat.animate(appbarlayout).translationy(168f).alpha(0.0f).setinterpolator(interpolator).withlayer()                     .setlistener(new viewpropertyanimatorlistener() {                         public void onanimationstart(view view) {                             bottomappbarlayoutbehavior.this.misanimatingout = true;                         }                          public void onanimationcancel(view view) {                             bottomappbarlayoutbehavior.this.misanimatingout = false;                         }                          public void onanimationend(view view) {                             bottomappbarlayoutbehavior.this.misanimatingout = false;                             view.setvisibility(view.gone);                         }                     }).start();         } else {             animation anim = animationutils.loadanimation(appbarlayout.getcontext(), r.anim.fab_out);             anim.setinterpolator(interpolator);             anim.setduration(200l);             anim.setanimationlistener(new animation.animationlistener() {                 public void onanimationstart(animation animation) {                     bottomappbarlayoutbehavior.this.misanimatingout = true;                 }                  public void onanimationend(animation animation) {                     bottomappbarlayoutbehavior.this.misanimatingout = false;                     appbarlayout.setvisibility(view.gone);                 }                  @override                 public void onanimationrepeat(final animation animation) {                 }             });             appbarlayout.startanimation(anim);         }     }      private void animatein(appbarlayout appbarlayout) {         appbarlayout.setvisibility(view.visible);         if (build.version.sdk_int >= 14) {             viewcompat.animate(appbarlayout).scalex(1.0f).scaley(1.0f).alpha(1.0f)                     .setinterpolator(interpolator).withlayer().setlistener(null)                     .start();         } else {             animation anim = animationutils.loadanimation(appbarlayout.getcontext(), r.anim.fab_in);             anim.setduration(200l);             anim.setinterpolator(interpolator);             appbarlayout.startanimation(anim);         }     } } 

i have found solution myself. appbarlayout wrapper bottom linearlayout redundant. remove appbarlayout wrapper , make behavior class extends coordinatorlayout.behavior<linearlayout>. add behavior linearlayout, top toolbar , bottom linearlayout enter , exit screen on scroll correctly.

the correct activity xml:

<android.support.design.widget.coordinatorlayout     android:layout_width="match_parent"     android:layout_height="match_parent"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:android="http://schemas.android.com/apk/res/android">      <android.support.design.widget.appbarlayout         android:layout_width="match_parent"         android:layout_height="wrap_content">          <android.support.v7.widget.toolbar             android:id="@+id/top_toolbar"             android:layout_width="fill_parent"             android:layout_height="wrap_content"             app:layout_scrollflags="scroll|enteralways" />      </android.support.design.widget.appbarlayout>      <framelayout         android:layout_width="fill_parent"         android:orientation="vertical"         app:layout_behavior="@string/appbar_scrolling_view_behavior"         android:id="@+id/recycler_view_container"         android:layout_height="fill_parent"/>      <linearlayout         android:id="@+id/bottom_bar"         android:layout_width="match_parent"         android:orientation="horizontal"         android:layout_height="wrap_content"         android:layout_gravity="bottom"         app:layout_behavior="*the_full_package_name*.linearlayoutbehavior ">         <!-- child views -->     </linearlayout>  </android.support.design.widget.coordinatorlayout> 

the correct behavior class:

public class linearlayoutbehavior extends coordinatorlayout.behavior<linearlayout> {     private static final interpolator interpolator = new fastoutslowininterpolator();     private boolean misanimatingout = false;      public linearlayoutbehavior(context context, attributeset attrs) {         super();     }      @override     public boolean onstartnestedscroll(final coordinatorlayout coordinatorlayout, final linearlayout child,                                        final view directtargetchild, final view target, final int nestedscrollaxes) {         return nestedscrollaxes == viewcompat.scroll_axis_vertical                 || super.onstartnestedscroll(coordinatorlayout, child, directtargetchild, target, nestedscrollaxes);     }      @override     public void onnestedscroll(final coordinatorlayout coordinatorlayout, final linearlayout child,                                final view target, final int dxconsumed, final int dyconsumed,                                final int dxunconsumed, final int dyunconsumed) {         super.onnestedscroll(coordinatorlayout, child, target, dxconsumed, dyconsumed, dxunconsumed, dyunconsumed);         if (dyconsumed > 0 && !this.misanimatingout && child.getvisibility() == view.visible) {             // user scrolled down , fab visible -> hide fab             animateout(child);         } else if (dyconsumed < 0 && child.getvisibility() != view.visible) {             // user scrolled , fab not visible -> show fab             animatein(child);         }     }      private void animateout(final linearlayout linearlayout) {         if (build.version.sdk_int >= 14) {             viewcompat.animate(linearlayout).translationy(168f).alpha(0.0f).setinterpolator(interpolator).withlayer()                     .setlistener(new viewpropertyanimatorlistener() {                         public void onanimationstart(view view) {                             linearlayoutbehavior.this.misanimatingout = true;                         }                          public void onanimationcancel(view view) {                             linearlayoutbehavior.this.misanimatingout = false;                         }                          public void onanimationend(view view) {                             linearlayoutbehavior.this.misanimatingout = false;                             view.setvisibility(view.gone);                         }                     }).start();         } else {             animation anim = animationutils.loadanimation(linearlayout.getcontext(), r.anim.fab_out);             anim.setinterpolator(interpolator);             anim.setduration(200l);             anim.setanimationlistener(new animation.animationlistener() {                 public void onanimationstart(animation animation) {                     linearlayoutbehavior.this.misanimatingout = true;                 }                  public void onanimationend(animation animation) {                     linearlayoutbehavior.this.misanimatingout = false;                     linearlayout.setvisibility(view.gone);                 }                  @override                 public void onanimationrepeat(final animation animation) {                 }             });             linearlayout.startanimation(anim);         }     }      private void animatein(linearlayout linearlayout) {         linearlayout.setvisibility(view.visible);         if (build.version.sdk_int >= 14) {             viewcompat.animate(linearlayout).translationy(0).scalex(1.0f).scaley(1.0f).alpha(1.0f)                     .setinterpolator(interpolator).withlayer().setlistener(null)                     .start();         } else {             animation anim = animationutils.loadanimation(linearlayout.getcontext(), r.anim.fab_in);             anim.setduration(200l);             anim.setinterpolator(interpolator);             linearlayout.startanimation(anim);         }     } } 

Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -