F.A.B 隐藏但不显示
F.A.B Hides but Doesn't Show
正在尝试实现向下滚动时隐藏、向上滚动时显示的 Floating Action Button
(F.A.B)。
我有 ScrollAwareFABBehavior.java
来管理它,它连接到 XML activity_main
中的 F.A.B。 问题: F.A.B 向下滚动时隐藏,但向上滚动时不再显示。我记录了 onNestedScroll
方法,它在向下滚动时调用了 "calling scroll" 和 "calling to hide";但是在 F.A.B 被隐藏之后,有 none 的 3x Log
的
问题:F.A.B被隐藏后,为什么向上滚动时F.A.B不显示
ScrollAwareFABBehavior.java:
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
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);
Log.d("test", "calling scroll");
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
// User scrolled down and the FAB is currently visible -> hide the FAB
Log.d("test", "calling to hide");
child.hide();
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
// User scrolled up and the FAB is currently not visible -> show the FAB
Log.d("test", "calling to show");
child.show();
}
}
}
activity_main.xml:
<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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="companyname.appname.MainActivity">
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rv_contactlist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:scrollbars="vertical" />
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_add_circle_outline_black_24dp"
app:layout_anchor="@id/rv_contactlist"
app:layout_anchorGravity="bottom|right|end"
android:layout_alignParentEnd="true"
app:fabSize="normal"
android:layout_alignParentBottom="true"
android:onClick="addItem"
app:layout_behavior="companyname.appname.ScrollAwareFABBehavior"/>
</android.support.design.widget.CoordinatorLayout>
您在项目中使用的是哪个支持库版本?
如果您使用的是最新的(我的意思是 25.0.x),这是因为 fab.hide() 方法将可见性设置为 View.GONE。这使得嵌套滚动侦听器停止检查 fab,第二次尝试滚动列表。
可以在此处找到更多详细信息:https://code.google.com/p/android/issues/detail?id=230298
然后我搜索了一下发现这个类似的问题已经有了很好的答案:
Floating action button not visible on scrolling after updating Google Support & Design Library
因此,一个可能的解决方法是重写 fab.hide 方法,而不是将可见性设置为 GONE 而是 INVISIBLE。
而且我认为这可能会在稍后从上游得到解决,所以请密切关注它。
使用之前建议的双重检查方法。一个fab可以同时显示和不可见,所以完美显示fab:
fab.show();
fab.setVisibility(View.VISIBLE);
因为 Android 更新为 25.0.x+ 你应该将带有监听器的 fab 按钮设置为 INVISBLE 以再次显示 fab 按钮,我的解决方案是下一个:
public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
private static final String TAG = "ScrollAwareFABBehavior";
public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
super();
}
@Override
public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
return true;
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
if(dependency instanceof RecyclerView)
return true;
return false;
}
@Override
public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
@Override
public void onHidden(FloatingActionButton fab) {
super.onHidden(fab);
fab.setVisibility(View.INVISIBLE);
}
}
);
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
child.show();
}
}
}
** 在带有 Android Oreo 的 Nexus 6P 中测试。
正在尝试实现向下滚动时隐藏、向上滚动时显示的 Floating Action Button
(F.A.B)。
我有 ScrollAwareFABBehavior.java
来管理它,它连接到 XML activity_main
中的 F.A.B。 问题: F.A.B 向下滚动时隐藏,但向上滚动时不再显示。我记录了 onNestedScroll
方法,它在向下滚动时调用了 "calling scroll" 和 "calling to hide";但是在 F.A.B 被隐藏之后,有 none 的 3x Log
的
问题:F.A.B被隐藏后,为什么向上滚动时F.A.B不显示
ScrollAwareFABBehavior.java:
import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
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);
Log.d("test", "calling scroll");
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
// User scrolled down and the FAB is currently visible -> hide the FAB
Log.d("test", "calling to hide");
child.hide();
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
// User scrolled up and the FAB is currently not visible -> show the FAB
Log.d("test", "calling to show");
child.show();
}
}
}
activity_main.xml:
<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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="companyname.appname.MainActivity">
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rv_contactlist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:scrollbars="vertical" />
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_add_circle_outline_black_24dp"
app:layout_anchor="@id/rv_contactlist"
app:layout_anchorGravity="bottom|right|end"
android:layout_alignParentEnd="true"
app:fabSize="normal"
android:layout_alignParentBottom="true"
android:onClick="addItem"
app:layout_behavior="companyname.appname.ScrollAwareFABBehavior"/>
</android.support.design.widget.CoordinatorLayout>
您在项目中使用的是哪个支持库版本?
如果您使用的是最新的(我的意思是 25.0.x),这是因为 fab.hide() 方法将可见性设置为 View.GONE。这使得嵌套滚动侦听器停止检查 fab,第二次尝试滚动列表。
可以在此处找到更多详细信息:https://code.google.com/p/android/issues/detail?id=230298
然后我搜索了一下发现这个类似的问题已经有了很好的答案: Floating action button not visible on scrolling after updating Google Support & Design Library
因此,一个可能的解决方法是重写 fab.hide 方法,而不是将可见性设置为 GONE 而是 INVISIBLE。
而且我认为这可能会在稍后从上游得到解决,所以请密切关注它。
使用之前建议的双重检查方法。一个fab可以同时显示和不可见,所以完美显示fab:
fab.show(); fab.setVisibility(View.VISIBLE);
因为 Android 更新为 25.0.x+ 你应该将带有监听器的 fab 按钮设置为 INVISBLE 以再次显示 fab 按钮,我的解决方案是下一个:
public class ScrollAwareFABBehavior extends FloatingActionButton.Behavior {
private static final String TAG = "ScrollAwareFABBehavior";
public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
super();
}
@Override
public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
return true;
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton child, View dependency) {
if(dependency instanceof RecyclerView)
return true;
return false;
}
@Override
public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child, @NonNull View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
@Override
public void onHidden(FloatingActionButton fab) {
super.onHidden(fab);
fab.setVisibility(View.INVISIBLE);
}
}
);
} else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) {
child.show();
}
}
}
** 在带有 Android Oreo 的 Nexus 6P 中测试。