如何在嵌套滚动上隐藏浮动操作按钮
How to hide Floating Action Button on Nested Scroll
我试图在 Nested Scroll 滚动时隐藏两个 FAB。我试图实现自己的 FAB 行为,但没有成功。 FAB 根本不会对滚动做出反应。注意:我删除了部分布局以适应 post.
布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="ru.berezin.maxim.im.budget_v3.userinterface.StartPage">
<android.support.design.widget.AppBarLayout
android:id="@+id/appcollapse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/testingscroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
app:behavior_overlapTop="30dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!--content including-->
<include layout="@layout/start_content_layout"/>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/start_page_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus"
app:layout_anchor="@id/testingscroll"
app:layout_anchorGravity="end|bottom"
app:layout_behavior="ru.berezin.maxim.im.budget_v3.FabOnScroll"
/>
<View
android:id="@+id/dummy"
android:layout_width="1dp"
android:layout_height="16dp"
app:layout_anchor="@id/start_page_fab"
app:layout_anchorGravity="top|right|end"
/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/account_det_add_transfer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|top"
android:layout_margin="16dp"
android:src="@drawable/minus"
app:layout_anchor="@id/dummy"
app:layout_anchorGravity="top|right|end"
app:layout_behavior="ru.berezin.maxim.im.budget_v3.FabOnScroll"
/>
</android.support.design.widget.CoordinatorLayout>
FabOnScroll class
public class FabOnScroll extends FloatingActionButton.Behavior {
public FabOnScroll(Context context, AttributeSet attrs) {
super();
}
@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);
//child -> Floating Action Button
if (dyConsumed > 0) {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
int fab_bottomMargin = layoutParams.bottomMargin;
child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start();
} else if (dyConsumed < 0) {
child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
}
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
}
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if (dy > 0 ||dy<0 && fab.isShown())
{
fab.hide();
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
{
if (newState == RecyclerView.SCROLL_STATE_IDLE)
{
fab.show();
}
super.onScrollStateChanged(recyclerView, newState);
}
});
所以,我修复了它。不完全是我想要的,但它正在工作。我不知道为什么,但出于某种原因,dyConsumed 始终等于 0。但我注意到 dyUnconsumed 在我滚动时正在变化。所以我只是将 dxUnconsumed 检查添加到我的 If/else 语句中并且它起作用了。有人可以解释为什么 dyConsumed 等于 0 吗?
我知道这是一个迟到的答案,但我的解决方案是在 if 语句中使用 dyUnconsumed 而不是 dyConsumed,它对我来说效果很好
if (dyUnconsumed > 0 && child.getVisibility() == View.VISIBLE) {
child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
@Override
public void onHidden(FloatingActionButton fab) {
super.onHidden(fab);
child.setVisibility(View.INVISIBLE);
}
});
} else if (dyUnconsumed <0 && child.getVisibility() != View.VISIBLE) {
child.show();
}
我试图在 Nested Scroll 滚动时隐藏两个 FAB。我试图实现自己的 FAB 行为,但没有成功。 FAB 根本不会对滚动做出反应。注意:我删除了部分布局以适应 post.
布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="ru.berezin.maxim.im.budget_v3.userinterface.StartPage">
<android.support.design.widget.AppBarLayout
android:id="@+id/appcollapse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="@+id/testingscroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
app:behavior_overlapTop="30dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!--content including-->
<include layout="@layout/start_content_layout"/>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:id="@+id/start_page_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="16dp"
android:src="@drawable/plus"
app:layout_anchor="@id/testingscroll"
app:layout_anchorGravity="end|bottom"
app:layout_behavior="ru.berezin.maxim.im.budget_v3.FabOnScroll"
/>
<View
android:id="@+id/dummy"
android:layout_width="1dp"
android:layout_height="16dp"
app:layout_anchor="@id/start_page_fab"
app:layout_anchorGravity="top|right|end"
/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/account_det_add_transfer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|top"
android:layout_margin="16dp"
android:src="@drawable/minus"
app:layout_anchor="@id/dummy"
app:layout_anchorGravity="top|right|end"
app:layout_behavior="ru.berezin.maxim.im.budget_v3.FabOnScroll"
/>
</android.support.design.widget.CoordinatorLayout>
FabOnScroll class
public class FabOnScroll extends FloatingActionButton.Behavior {
public FabOnScroll(Context context, AttributeSet attrs) {
super();
}
@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);
//child -> Floating Action Button
if (dyConsumed > 0) {
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
int fab_bottomMargin = layoutParams.bottomMargin;
child.animate().translationY(child.getHeight() + fab_bottomMargin).setInterpolator(new LinearInterpolator()).start();
} else if (dyConsumed < 0) {
child.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
}
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
}
}
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy)
{
if (dy > 0 ||dy<0 && fab.isShown())
{
fab.hide();
}
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState)
{
if (newState == RecyclerView.SCROLL_STATE_IDLE)
{
fab.show();
}
super.onScrollStateChanged(recyclerView, newState);
}
});
所以,我修复了它。不完全是我想要的,但它正在工作。我不知道为什么,但出于某种原因,dyConsumed 始终等于 0。但我注意到 dyUnconsumed 在我滚动时正在变化。所以我只是将 dxUnconsumed 检查添加到我的 If/else 语句中并且它起作用了。有人可以解释为什么 dyConsumed 等于 0 吗?
我知道这是一个迟到的答案,但我的解决方案是在 if 语句中使用 dyUnconsumed 而不是 dyConsumed,它对我来说效果很好
if (dyUnconsumed > 0 && child.getVisibility() == View.VISIBLE) {
child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
@Override
public void onHidden(FloatingActionButton fab) {
super.onHidden(fab);
child.setVisibility(View.INVISIBLE);
}
});
} else if (dyUnconsumed <0 && child.getVisibility() != View.VISIBLE) {
child.show();
}