Кнопка плавающего действия не отображается при прокрутке после обновления библиотеки поддержки и дизайна Google
Я пробовал обновлять com.android.support:appcompat
и com.android.support:design
от: 25.0.1 до 25.1.0 следующим образом:
compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.android.support:design:25.0.1'
в
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:design:25.1.0'
но я обнаружил, что моя кнопка с плавающим действием больше не появляется при прокрутке активности. Мое поведение FAB определяется следующим образом:
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();
}
}
}
и мой макет выглядит следующим образом:
<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>
Ответы
Ответ 1
Обновление из поддержки lib 25.0.1
до 25.1.0
изменяет метод onNestedScroll
CoordinatorLayout
тем, что вызов пропускается для представлений, чья видимость установлена на View.GONE
.
Вызов child.hide()
в кнопке с плавающим действием устанавливает видимость вида View.GONE
, что означает теперь (начиная с 25.1.0), вызов метода onNestedScroll
будет пропущен для кнопки плавающего действия в будущем ( потому что он пропускает все представления, видимость которых GONE
).
Обходным путем для этого было бы установить видимость вида INVISIBLE
всякий раз, когда вы его скроете. Таким образом, onNestedScroll
не будет пропускать представление в следующий раз, когда выполняется вложенная прокрутка.
Чтобы достичь этого, вы можете позвонить
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);
}
});
в вашем методе onNestedScroll
.
Изменить: этот вопрос был отправлен в AOSP Issue Tracker по адресу https://code.google.com/p/android/issues/detail?id=230298
Ответ 2
в 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;
}
в 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;
}
Ответ 3
Поведение изменилось с версии поддержки lib 25.1.0
.
Это должно быть RecyclerView (Поведение), которое вызывает изменение видимости FAB.
Другими словами, это уже не ответственность объекта, который хочет реагировать на поведение, а на объект, который движется, чтобы знать обо всем на экране.
Ниже приведена ссылка на diff, которая показывает изменения, необходимые для выполнения обновления:
https://github.com/chrisbanes/cheesesquare/compare/master...ianhanniballake:scroll_aware_fab