Использование Google Design Library, как скрыть кнопку FAB в прокрутке вниз?
Google выпустила библиотеку Design, я использую
compile 'com.android.support:design:22.2.1'
Однако я не вижу каких-либо примеров кода, как использовать эту библиотеку и как анимировать панель FAB для прокрутки. Я предполагаю, что могу прослушивать события прокрутки в ListView, а затем сама анимация кнопки, но это не запекается в API (это не проблема этой библиотеки поддержки).
Есть ли примеры?
Спасибо
Ответы
Ответ 1
Если вы используете RecyclerView
, и вы ищете что-то простое, вы можете попробовать следующее:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy){
if (dy > 0)
fabAddNew.hide();
else if (dy < 0)
fabAddNew.show();
}
});
Заменяя 0
на константу, вы можете настроить чувствительность запуска, обеспечивая более плавное воспроизведение
Ответ 2
Выполнение реакции компонента на события прокрутки наиболее легко выполняется с помощью CoordinatorLayout.Behavior, поскольку они автоматически получают события прокрутки при переопределении onStartNestedScroll().
Пример поведения, который скрывает и показывает FAB на свитке, найденном в этом FABAwareScrollingViewBehavior, построенном поверх cheesesquare:
public class FABAwareScrollingViewBehavior
extends AppBarLayout.ScrollingViewBehavior {
public FABAwareScrollingViewBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent,
View child, View dependency) {
return super.layoutDependsOn(parent, child, dependency) ||
dependency instanceof FloatingActionButton;
}
@Override
public boolean onStartNestedScroll(
final CoordinatorLayout coordinatorLayout, final View 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 View 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) {
// User scrolled down -> hide the FAB
List<View> dependencies = coordinatorLayout.getDependencies(child);
for (View view : dependencies) {
if (view instanceof FloatingActionButton) {
((FloatingActionButton) view).hide();
}
}
} else if (dyConsumed < 0) {
// User scrolled up -> show the FAB
List<View> dependencies = coordinatorLayout.getDependencies(child);
for (View view : dependencies) {
if (view instanceof FloatingActionButton) {
((FloatingActionButton) view).show();
}
}
}
}
}
Если в вашем прокрутке будет app:layout_behavior="com.support.android.designlibdemo.FABAwareScrollingViewBehavior"
вместо app:layout_behavior="@string/appbar_scrolling_view_behavior"
Однако вы можете заменить hide()
и show()
на любое действие, если хотите. Подробности о том, как это было сделано, можно найти в этот пост и следить сообщение для v22.2.1 и последующее сообщение для v25.1.0.
Обратите внимание, что это, как и все прокрутки поведения библиотеки дизайна, требует, чтобы ваше представление поддерживало вложенную прокрутку, которая в настоящее время ограничивает вас NestedScrollView, RecyclerView - ListView
и ScrollView
работают только с устройствами API21 +.
Ответ 3
Использование CoordinatorLayout - лучший способ.
Если вы хотите подключить слушателя к ListView или RecyclerView, вы также можете это сделать.
Я думаю, что это более настраиваемый.
Вот мой пример в концентраторе git.
Проект Github: Скрыть FAB (библиотека материалов) со списком
![введите описание изображения здесь]()
Ответ 4
Я знаю, что я опаздываю, но в случае, если кто-то приходит сюда, чтобы найти ответы, этот работал у меня. Да, и @TargetApi(23)
требуется, так как setOnScrollChangeListener()
не работает под 22 API.
@TargetApi(23)
void hideFabOnScroll(){
webView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
if (scrollY > oldScrollY)
fab.hide();
else if (scrollY < oldScrollY)
fab.show();
}
});
}
Ответ 5
Функция @ianhanniballake работает нормально, но методы onStartNestedScroll()
и onNestedScroll()
устарели. Вот обновленная версия:
public class FabAwareScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {
public FabAwareScrollingViewBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
return super.layoutDependsOn(parent, child, dependency) ||
dependency instanceof FloatingActionButton;
}
@Override
public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull View child, @NonNull View directTargetChild,
@NonNull View target, int axes, int type) {
// Ensure we react to vertical scrolling
return axes == ViewCompat.SCROLL_AXIS_VERTICAL ||
super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type);
}
@Override
public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull View child, @NonNull View target, int dx, int dy,
@NonNull int[] consumed, int type) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
if (dy > 0) {
// User scrolled down -> hide the FAB
List<View> dependencies = coordinatorLayout.getDependencies(child);
for (View view : dependencies) {
if (view instanceof FloatingActionButton) {
((FloatingActionButton) view).hide();
}
}
} else if (dy < 0) {
// User scrolled up -> show the FAB
List<View> dependencies = coordinatorLayout.getDependencies(child);
for (View view : dependencies) {
if (view instanceof FloatingActionButton) {
((FloatingActionButton) view).show();
}
}
}
}
}
Также есть очень хорошая публикация @ianhanniballake по этой теме: Перехватывать все с помощью CoordinatorLayout Behaviors
Ответ 6
Если вы используете NOT с помощью RecycleView (то есть просто обычного ScrollView), это будет делать трюк:
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
if (mScrollView.getScrollY() > oldScrollYPostion) {
fab.hide();
} else if (mScrollView.getScrollY() < oldScrollYPostion || mScrollView.getScrollY() <= 0) {
fab.show();
}
oldScrollYPostion = mScrollView.getScrollY();
}
});
Не забудьте объявить:
private int oldScrollYPostion = 0;
внутри вашего класса.