Menu y Autohide FloatingActionButton de Android Design Support Library

Estoy usando Android Design Support Library y quiero un FloatingActionButton que tenga AutoHide por Scrolling,

Mi diseño es:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:id="@+id/scrollView" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/LargeText" /> </ScrollView> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_anchorGravity="bottom|right|end" app:layout_anchor="@id/scrollView" android:src="@drawable/abc_btn_rating_star_off_mtrl_alpha" /> </android.support.design.widget.CoordinatorLayout> 

FloatingActionButton que muestra siempre al desplazar el texto, quiero ocultarlo automáticamente al desplazar el texto.

Y, quiero tener un menú FloatingActionButton haciendo clic en FloatingActionButton, como esto:

Introduzca aquí la descripción de la imagen

FloatingActionButton que tiene AutoHide por Desplazamiento,

Debe utilizar android.support.v4.widget.NestedScrollView lugar de ScrollView . No puede utilizar ScrollView. Debe utilizar el NestedScrollView o una vista que implemente la interfaz NestedScrollingChild, como un RecyclerView.

Para lograr este tipo de patrón que tiene que implementar su Behavior personalizado. Hay un bonito código publicado por un Googler que oculta el FAB cuando el usuario se desplaza hacia abajo y lo muestra cuando se desplaza hacia arriba. Reutiliza la misma animación que FloatingActionButton.Behavior utiliza para ocultar / mostrar el FAB en reacción a la salida / entrada de AppBarLayout.

ACTUALIZADO 18/07/2015

Con el 22.2.1 simplemente puede agregar el código publicado a continuación, utilizando las animaciones preconstruidas. Sólo usa una clase como esta: (fuente original aquí )

 public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior { public ScrollAwareFABBehavior(Context context, AttributeSet attrs) { super(); } @Override public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child, final View directTargetChild, final View target, final int nestedScrollAxes) { // Ensure we react to vertical scrolling return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); } @Override public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton 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 && child.getVisibility() == View.VISIBLE) { // User scrolled down and the FAB is currently visible -> hide the FAB child.hide(); } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { // User scrolled up and the FAB is currently not visible -> show the FAB child.show(); } } } 

A continuación, puede aplicar este comportamiento a su FAB utilizando:

 <android.support.design.widget.FloatingActionButton android:id="@+id/fab" app:layout_behavior="com.support.android.designlibdemo.ScrollAwareFABBehavior" /> 

Con Diseño 22.2.0 : Tienes que usar una clase como esta: (fuente original aquí )

 public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior { private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); private boolean mIsAnimatingOut = false; public ScrollAwareFABBehavior(Context context, AttributeSet attrs) { super(); } @Override public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child, final View directTargetChild, final View target, final int nestedScrollAxes) { // Ensure we react to vertical scrolling return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); } @Override public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton 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 and the FAB is currently visible -> hide the FAB animateOut(child); } else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) { // User scrolled up and the FAB is currently not visible -> show the FAB animateIn(child); } } // Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits private void animateOut(final FloatingActionButton button) { if (Build.VERSION.SDK_INT >= 14) { ViewCompat.animate(button).scaleX(0.0F).scaleY(0.0F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer() .setListener(new ViewPropertyAnimatorListener() { public void onAnimationStart(View view) { ScrollAwareFABBehavior.this.mIsAnimatingOut = true; } public void onAnimationCancel(View view) { ScrollAwareFABBehavior.this.mIsAnimatingOut = false; } public void onAnimationEnd(View view) { ScrollAwareFABBehavior.this.mIsAnimatingOut = false; view.setVisibility(View.GONE); } }).start(); } else { Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_out); anim.setInterpolator(INTERPOLATOR); anim.setDuration(200L); anim.setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation animation) { ScrollAwareFABBehavior.this.mIsAnimatingOut = true; } public void onAnimationEnd(Animation animation) { ScrollAwareFABBehavior.this.mIsAnimatingOut = false; button.setVisibility(View.GONE); } @Override public void onAnimationRepeat(final Animation animation) { } }); button.startAnimation(anim); } } // Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters private void animateIn(FloatingActionButton button) { button.setVisibility(View.VISIBLE); if (Build.VERSION.SDK_INT >= 14) { ViewCompat.animate(button).scaleX(1.0F).scaleY(1.0F).alpha(1.0F) .setInterpolator(INTERPOLATOR).withLayer().setListener(null) .start(); } else { Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.fab_in); anim.setDuration(200L); anim.setInterpolator(INTERPOLATOR); button.startAnimation(anim); } } } 

A continuación, puede aplicar este comportamiento a su FAB utilizando:

 <android.support.design.widget.FloatingActionButton android:id="@+id/fab" app:layout_behavior="com.support.android.designlibdemo.ScrollAwareFABBehavior" /> 

Por supuesto, puede cambiar este código para obtener su patrón favorito.

Y, quiero tener un menú FloatingActionButton haciendo clic en FloatingActionButton, como esto:

Actualmente, el FAB original no admite este patrón. Tienes que implementar un código personalizado para lograrlo.

Puedes lograrlo

Aquí está mi código.

Paso 1:

Primero haz Getter de FloatingActionMenu para que puedas llamarlo desde otra actividad o desde fragmento donde se usa tu recycleview

 public FloatingActionMenu getFloatingActionMenu() { return fabMenu; } 

Paso 2:

Llame debajo de la línea de otra actividad o de fragmento

  FloatingActionMenu fabMenu=((MainActivity)getActivity()).getFloatingActionMenu(); 

Paso 3:

Ahora compruebe cuánto recycleview está desplazándose o no depende de la posición "dy" Aquí he usado la animación fabMenu

 Animation FabMenu_fadOut = AnimationUtils.loadAnimation(getActivity(), R.anim.fade_out); Animation FabMenu_fadIn = AnimationUtils.loadAnimation(getActivity(), R.anim.abc_grow_fade_in); recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); if (dy > 0 && floatingActionButton.isShown()) { //fabMenu.startAnimation(FabMenu_fadIn); fabMenu.setVisibility(View.GONE); } if (dy < 0 && !floatingActionButton.isShown()) { // fabMenu.startAnimation(FabMenu_fadOut); fabMenu.setVisibility(View.VISIBLE); } } }); 

Nota: Si desea ocultar FloatingActionButton en desplazamiento, utilice el mismo código que en FloatingActionMenu.

Gracias.

Usted puede implementar el menú de acción flotante usando esto .

En cuanto al menú de animación para acciones flotantes, puede crear una clase llamada ScrollAwareFloatingActionMenuBehaviour:

 public class ScrollAwareFloatingActionMenuBehaviour extends CoordinatorLayout.Behavior<FloatingActionsMenu> { private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); private boolean mIsAnimatingOut = false; private boolean mIsAnimatingIn = false; public ScrollAwareFloatingActionMenuBehaviour(Context context, AttributeSet attrs) { } @Override public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionsMenu child, View dependency) { return dependency instanceof Snackbar.SnackbarLayout; } @Override public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionsMenu child, View dependency) { float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight()); child.setTranslationY(translationY); return true; } @Override public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionsMenu child, View directTargetChild, View target, int nestedScrollAxes) { return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes); } @Override public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionsMenu child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); if (dyConsumed > 10 && !this.mIsAnimatingOut && !this.mIsAnimatingIn && child.getVisibility() == View.VISIBLE) { // User scrolled down and the FAB is currently visible -> hide the FAB animateOut(child); } else if (dyConsumed < -10 && !this.mIsAnimatingOut && !this.mIsAnimatingIn && child.getVisibility() != View.VISIBLE) { // User scrolled up and the FAB is currently not visible -> show the FAB animateIn(child); } } // Same animation that FloatingActionButton.Behavior uses to hide the FAB when the AppBarLayout exits private void animateOut(final FloatingActionsMenu button) { if (Build.VERSION.SDK_INT >= 14) { ViewCompat.animate(button).translationYBy(200F).alpha(0.0F).setInterpolator(INTERPOLATOR).withLayer() .setListener(new ViewPropertyAnimatorListener() { public void onAnimationStart(View view) { ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = true; } public void onAnimationCancel(View view) { ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = false; } public void onAnimationEnd(View view) { ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = false; view.setVisibility(View.GONE); } }).start(); } else { Animation anim = AnimationUtils.loadAnimation(button.getContext(), R.anim.design_fab_out); anim.setInterpolator(INTERPOLATOR); anim.setDuration(200L); anim.setAnimationListener(new Animation.AnimationListener() { public void onAnimationStart(Animation animation) { ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = true; } public void onAnimationEnd(Animation animation) { ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingOut = false; button.setVisibility(View.GONE); } @Override public void onAnimationRepeat(final Animation animation) { } }); button.startAnimation(anim); } } // Same animation that FloatingActionButton.Behavior uses to show the FAB when the AppBarLayout enters private void animateIn(FloatingActionsMenu button) { button.setVisibility(View.VISIBLE); if (Build.VERSION.SDK_INT >= 14) { ViewCompat.animate(button).translationYBy(-200F).alpha(1.0F) .setInterpolator(INTERPOLATOR).withLayer().setListener(new ViewPropertyAnimatorListener() { @Override public void onAnimationStart(View view) { ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingIn = true; } @Override public void onAnimationEnd(View view) { ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingIn = false; } @Override public void onAnimationCancel(View view) { ScrollAwareFloatingActionMenuBehaviour.this.mIsAnimatingIn = false; } }) .start(); } else { Animation anim = AnimationUtils.loadAnimation(button.getContext(), android.support.design.R.anim.design_fab_in); anim.setDuration(200L); anim.setInterpolator(INTERPOLATOR); button.startAnimation(anim); } } } 

Observe que R.anim.fab_in y R.anim.fab_out son reemplazados por R.anim.design_fab_in y R.anim.design_fab_out respectivamente.

Utilícelo en el xml:

 <com.getbase.floatingactionbutton.FloatingActionsMenu xmlns:fab="http://schemas.android.com/apk/res-auto" android:id="@+id/fab_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end|bottom" android:layout_margin="@dimen/fab_margin" fab:fab_addButtonColorNormal="@color/colorAccent" fab:fab_addButtonColorPressed="@color/colorAccentLight" fab:fab_addButtonPlusIconColor="@android:color/white" app:layout_behavior="com.example.widgets.behaviour.ScrollAwareFloatingActionMenuBehaviour" fab:fab_labelStyle="@style/menu_labels_style" fab:fab_labelsPosition="left"> <com.getbase.floatingactionbutton.FloatingActionButton android:id="@+id/fab_share" android:layout_width="wrap_content" android:layout_height="wrap_content" fab:fab_colorNormal="@color/fab_normal_blue" fab:fab_colorPressed="@color/fab_normal_blue_pressed" fab:fab_icon="@drawable/ic_social_share" fab:fab_title="@string/fab_menu_group_chat" /> </com.getbase.floatingactionbutton.FloatingActionsMenu> 
  • El botón de acción flotante no sube cuando la barra de Snack está mostrando en android
  • ¿Cómo agregar texto al botón de acción flotante?
  • Biblioteca de soporte de diseño de Android
  • 25.1.0 La librería de soporte de Android está rompiendo el comportamiento fabuloso
  • Cómo cambiar el diseño de android biblioteca de soporte FAB Button color de la frontera?
  • ¿Cómo puedo conseguir el selector de marcación rápida android fab?
  • Diseño de Android
  • Bug con FloatingActionButton anclado en la biblioteca de soporte 24.2.1
  • Android: Crear un botón de acción flotante más grande con un icono más grande
  • Android: FloatingActionButton no se pudo instanciar
  • Recyclerview exterior no recibe eventos de desplazamiento de Recyclerview interno
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.