android - last - El botón de acción flotante no se ve en el desplazamiento después de actualizar Google Support & Design Library
com.android.support:appcompat-v7 last version (3)
El comportamiento ha cambiado desde el soporte de la versión lib 25.1.0
.
Debe ser RecyclerView (Comportamiento) el que activa el cambio de visibilidad de FAB.
En otras palabras, ya no es responsabilidad del objeto que quiere reaccionar tener un comportamiento, sino del objeto que se mueve para estar al tanto de todo lo que aparece en la pantalla.
A continuación se muestra un enlace a un diff que muestra los cambios necesarios para realizar la actualización:
https://github.com/chrisbanes/cheesesquare/compare/master...ianhanniballake:scroll_aware_fab
He intentado actualizar com.android.support:appcompat
y com.android.support:design
desde: 25.0.1 a 25.1.0, de la siguiente manera:
compile ''com.android.support:appcompat-v7:25.0.1''
compile ''com.android.support:design:25.0.1''
a:
compile ''com.android.support:appcompat-v7:25.1.0''
compile ''com.android.support:design:25.1.0''
pero he encontrado que mi botón de acción flotante ya no aparece cuando la actividad se desplaza. Mi comportamiento FAB se define por lo siguiente:
public class MyFabBehavior extends FloatingActionButton.Behavior {
public MyFabBehavior(Context context, AttributeSet attrs) {
super();
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout,
FloatingActionButton child, View directTargetChild, View target, 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(CoordinatorLayout coordinatorLayout, FloatingActionButton child,
View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
if (dyConsumed < 0) {
// User scrolled up -> hide the FAB
animateFab(child, View.GONE);
} else if (dyConsumed > 0) {
// User scrolled down -> show the FAB
animateFab(child, View.VISIBLE);
}
}
static public void animateFab(FloatingActionButton fab, int visibility) {
// ignore visibility passed in, and just make fab visible regardless
if (fab.getVisibility() != View.VISIBLE) {
fab.show();
}
}
}
y mi diseño es el siguiente:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<android.support.v4.widget.NestedScrollView
android:id="@+id/main_scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp" >
...
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
app:layout_behavior="com.example.MyFabBehavior"
android:id="@+id/fab"
app:fabSize="normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_marginRight="@dimen/fab_margin"
android:onClick="saveButton"
app:elevation="6dp"
app:pressedTranslationZ="12dp"
app:backgroundTint="@color/colorPrimary"
android:src="@drawable/ic_done_white_24dp" />
</android.support.design.widget.CoordinatorLayout>
La actualización de la 25.0.1
de soporte 25.0.1
a 25.1.0
cambia el método onNestedScroll
de CoordinatorLayout
en el sentido de que la llamada se omite para las vistas cuya visibilidad se establece en View.GONE
.
Al llamar a child.hide()
en el botón de acción flotante, se establece la visibilidad de la vista en View.GONE
, lo que significa que ahora (a partir del 25.1.0), la onNestedScroll
método onNestedScroll
se omitirá para el botón de acción flotante en el futuro (porque salta todas las vistas cuya visibilidad se haya GONE
).
Una solución para esto sería establecer la visibilidad de la vista en INVISIBLE
cada vez que la oculte. De esta manera, onNestedScroll
no omitirá la vista la próxima vez que se realice un desplazamiento anidado.
Para lograr esto, puedes llamar
child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
/**
* Called when a FloatingActionButton has been hidden
*
* @param fab the FloatingActionButton that was hidden.
*/
@Override
public void onHidden(FloatingActionButton fab) {
super.onShown(fab);
fab.setVisibility(View.INVISIBLE);
}
});
en su método onNestedScroll
.
Edición: este problema se ha enviado al AOSP Issue Tracker en https://code.google.com/p/android/issues/detail?id=230298
en CoordinatorLayout 25.1.0 (
for (int i = 0; i < childCount; i++) {
final View view = getChildAt(i);
if (view.getVisibility() == GONE) {
// If the child is GONE, skip...
continue;
}
en 25.0.1
for (int i = 0; i < childCount; i++) {
final View view = getChildAt(i);
final LayoutParams lp = (LayoutParams) view.getLayoutParams();
if (!lp.isNestedScrollAccepted()) {
continue;
}
final Behavior viewBehavior = lp.getBehavior();
if (viewBehavior != null) {
viewBehavior.onNestedScroll(this, view, target, dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed);
accepted = true;
}