FloatingActionButton 不隐藏
FloatingActionButton doesn't hide
我正在尝试以编程方式隐藏我的 FloatingActionButton fabLocation
:
fabLocation.setVisibility(View.GONE)
但它不起作用。
如果我在我的 XML 布局中添加 android:visibility="gone"
,当我 运行 我的 activity 时 fabLocation
是隐藏的,但当我滚动时它会重新出现。
这是我的布局:
<?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"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="@color/colorOverlay"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/img_couverture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/bg_navigation_drawer_header"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp" />
<View
android:background="@drawable/separator_orange_gradient"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:layout_width="match_parent"
android:layout_height="2dp"/>
<TextView
android:id="@+id/tv_history"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.RobotoLight" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:id="@+id/fab_location"
android:src="@drawable/ic_fab_location_24dp"
app:backgroundTint="@color/colorOrange"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end" />
这是由于 app:layout_anchor
属性。在更改可见性之前,您必须先删除锚点:
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setAnchorId(View.NO_ID);
fab.setLayoutParams(p);
fab.setVisibility(View.GONE);
如果要显示隐藏FAB
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
...
</android.support.design.widget.AppBarLayout>
...
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:visibility="gone"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:clickable="true"/>
</android.support.design.widget.CoordinatorLayout>
和
CoordinatorLayout.LayoutParams p = new CoordinatorLayout.LayoutParams(CoordinatorLayout.LayoutParams.WRAP_CONTENT, CoordinatorLayout.LayoutParams.WRAP_CONTENT);
p.anchorGravity = Gravity.BOTTOM | Gravity.END;
p.setAnchorId(R.id.appbar);
p.setMargins(...);
fab.setLayoutParams(p);
fab.setVisibility(View.VISIBLE);
None 这些其他解决方案帮助了我 100%。我需要重复动画显示和隐藏(如 FAB.show()
和 hide()
),同时在可见时锚定到应用栏。
我每次展示它时都会创建新的 FAB,手动插入和锚定它,并根据支持库实现为其设置动画。这很恶心,但效果很好。
private void hidePlayButton(final FloatingActionButton fab) {
// Cancel any animation from the default behavior
fab.animate().cancel();
fab.animate()
.scaleX(0f)
.scaleY(0f)
.alpha(0f)
.setDuration(200)
.setInterpolator(new FastOutLinearInInterpolator())
.setListener(new Animator.AnimatorListener() {
@Override public void onAnimationStart(Animator animation) {}
@Override public void onAnimationEnd(Animator animation) {
coordinatorLayout.removeView(fab);
}
@Override public void onAnimationCancel(Animator animation) {}
@Override public void onAnimationRepeat(Animator animation) {}
});
}
private void showPlayButton() {
int fabSize = getResources().getDimensionPixelSize(R.dimen.fab_size);
int margin = getResources().getDimensionPixelSize(R.dimen.fab_margin);
final FloatingActionButton fab = new FloatingActionButton(getActivity());
fab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getActivity(), R.color.tint)));
fab.setImageDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.play));
CoordinatorLayout.LayoutParams p = new CoordinatorLayout.LayoutParams(fabSize, fabSize);
p.rightMargin = p.leftMargin = p.bottomMargin = p.topMargin = margin;
p.anchorGravity = Gravity.BOTTOM | Gravity.END;
p.setAnchorId(R.id.appbar);
fab.setLayoutParams(p);
// Start from 1 pixel
fab.setAlpha(0f);
fab.setScaleX(0f);
fab.setScaleY(0f);
binding.coordinatorLayout.addView(fab);
fab.animate()
.alpha(1f)
.scaleX(1f)
.scaleY(1f)
.setDuration(200)
.setInterpolator(new FastOutLinearInInterpolator());
fab.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
hidePlayButton(fab);
// do action
}
});
}
简单代码:
public static void setVisibilityFab(FloatingActionButton fab, int visibility)
{
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setAnchorId(View.NO_ID);
fab.setLayoutParams(p);
if(visibility==View.GONE || visibility==View.INVISIBLE)
fab.setVisibility(View.GONE);
else
fab.setVisibility(View.VISIBLE);
}
经过一些回答后,我找到了解决我的问题的方法(当 fab 被隐藏时它可以处理动作!)。
首先我建议您将.setVisibility(View.GONE)
和.setVisibility(View.VISIBLE)
替换为.show()
和.hide()
方法。这些最后句柄也 actionMode
.
对我来说第二个问题是隐藏 fab 时也处理的操作,为了解决这个问题我做到了:
final CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams)floatingActionButton.getLayoutParams();
if (show){
p.setAnchorId(R.id.appBarLayout);
p.width = CoordinatorLayout.LayoutParams.WRAP_CONTENT;
p.height = CoordinatorLayout.LayoutParams.WRAP_CONTENT;
floatingActionButton.setLayoutParams(p);
floatingActionButton.show();
}else{
p.setAnchorId(View.NO_ID);
p.width = 0;
p.height = 0;
floatingActionButton.setLayoutParams(p);
floatingActionButton.hide();
}
我知道您的回答是关于如何使其适用于 gone
可见性,但如果您使用 invisible
而不是,您将不用担心,而且代码更少。
我通过使用布局边距将 FAB 放置在屏幕内或屏幕外来解决 show()/hide() 的缺点。示例:
CoordinatorLayout.LayoutParams p =
new CoordinatorLayout.LayoutParams(
CoordinatorLayout.LayoutParams.WRAP_CONTENT,
CoordinatorLayout.LayoutParams.WRAP_CONTENT);
p.gravity = Gravity.BOTTOM | Gravity.LEFT;
int fabMargin = (int)res.getDimension(R.dimen.fab_margin);
if( enabled ) {
p.setMargins(fabMargin,0,0,fabMargin);
}
else {
p.setMargins(-200,0,0,fabMargin);
}
mFab.setLayoutParams(p);
我用这个代码:
boolean mFabShouldBeShown;
FloatingActionButton.OnVisibilityChangedListener fabListener = new FloatingActionButton.OnVisibilityChangedListener() {
@Override
public void onShown(FloatingActionButton fab) {
super.onShown(fab);
if(!mFabShouldBeShown){
fab.hide();
}
}
@Override
public void onHidden(FloatingActionButton fab) {
super.onHidden(fab);
if(mFabShouldBeShown){
fab.show();
}
}
};
public void methodWhereFabIsHidden() {
mFabShouldBeShown = false;
mFloatingActionButton.hide(fabListener);
}
public void methodWhereFabIsShown() {
mFabShouldBeShown = true;
mFloatingActionButton.show(fabListener);
}
真正解决你问题的办法是subclass默认FloatingActionButton.Behavior
在它们的构造函数中调用setAutoHide(false)
,这样你就可以自己控制了。
请注意,我在下面谈论底部 sheets,但对于所有锚定的浮动操作按钮来说都是完全相同的问题,它确实回答了问题并且应该解决了问题不出所料。
或者,您可以覆盖自定义行为中的 boolean onDependentViewChanged(…)
方法,复制 FloatingActionButton.Behavior
class 中存在的 isBottomSheet(…)
静态方法,并且只调用 & return super 方法的值如果不是底部 sheet.
您可以通过这种方式进一步自定义默认行为,或者通过直接扩展香草 CoordinatorLayout.Behavior
class,您可以挑选代码从 FloatingActionButton.Behavior
class 如果需要的话。
这是我用来控制 FAB 可见性的代码:
/**
* Allows controlling the FAB visibility manually.
*/
@SuppressWarnings("unused")
public class FabManualHideBehavior extends FloatingActionButton.Behavior {
public FabManualHideBehavior() {
super();
setAutoHideEnabled(false);
}
public FabManualHideBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
setAutoHideEnabled(false);
}
}
我在 xml 中以这种方式将其应用到我的 FAB:
<android.support.design.widget.CoordinatorLayout
...>
...
<android.support.design.widget.FloatingActionButton
...
app:layout_anchor="@+id/bottom_sheet"
app:layout_anchorGravity="top|end"
app:layout_behavior="your.package.name.ui.behavior.FabManualHideBehavior"/>
</android.support.design.widget.CoordinatorLayout>
这是简单的解决方案
private var fabAnchorId: Int = View.NO_ID
private val fabParams: CoordinatorLayout.LayoutParams
get() = (fab.layoutParams as CoordinatorLayout.LayoutParams)
fun showFab() {
fabParams.anchorId = fabAnchorId
fabParams.gravity = Gravity.NO_GRAVITY
fab.show()
}
fun hideFab() {
fabParams.anchorId = View.NO_ID
fabParams.gravity = Gravity.END.or(Gravity.BOTTOM)
fab.hide()
}
在show/hide之前我们必须改变锚点和重力
锚定到 AppBarLayout 的 FloatingActionButtons 有一种特殊的关系,它们的可见性由 AppBarLayout 的滚动位置控制。
您可以通过 behavior_autoHide
属性关闭此功能:
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="..."
app:behavior_autoHide="false"/>
如果您愿意,您也可以通过编程方式执行此操作:
编辑:
fab.getBehavior() 不正确,使用 LayoutParams
中的 getBehavior()
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
FloatingActionButton.Behavior behavior = (FloatingActionButton.Behavior) lp.getBehavior();
if (behavior != null) {
behavior.setAutoHideEnabled(false);
} else {
behavior = new FloatingActionButton.Behavior();
behavior.setAutoHideEnabled(false);
lp.setBehavior(behavior);
}
我对发布的任何解决方案都不满意。有些只工作了一部分时间,而另一些只工作了 fab.setVisibility()
。虽然我知道这在技术上是原始问题所问的问题,但一些回复表示有兴趣使用 fab.hide()
,并且弄乱布局参数并不能完全解决问题的根源。
正如@ChrisBanes 所指出的,FloatingActionButton.Behavior
与 AppBarLayout
绑定是导致问题的原因。因此,与他的回答一样,您必须 setAutoHideEnabled(false)
才能禁用该功能。但是,如果您确实希望 FloatingActionButton
在手动调用 hide()
时自动隐藏 和 ,则此解决方案无济于事。
所以为了做到这一点;我只是在手动隐藏 Button
之前禁用自动隐藏功能,然后在手动显示 Button
:
后重新启用该功能
private void hideFloatingActionButton(FloatingActionButton fab) {
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) fab.getLayoutParams();
FloatingActionButton.Behavior behavior =
(FloatingActionButton.Behavior) params.getBehavior();
if (behavior != null) {
behavior.setAutoHideEnabled(false);
}
fab.hide();
}
private void showFloatingActionButton(FloatingActionButton fab) {
fab.show();
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) fab.getLayoutParams();
FloatingActionButton.Behavior behavior =
(FloatingActionButton.Behavior) params.getBehavior();
if (behavior != null) {
behavior.setAutoHideEnabled(true);
}
}
如果你想隐藏fab,你可以试试这个:
fab.hide();
否则试试
fab.show();
享受。
FloatingActionButton layers = (FloatingActionButton) findViewById(R.id.layers);
layers.hide();
它适用于我,setVisibility
不适用于 FloatingActionButton
,因为它属于另一个没有 setVisibility
方法的 viewGroup
。
隐藏浮动按钮
fab = (FloatingActionButton) findViewById(R.id.fab);
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setAnchorId(View.NO_ID);
fab.setLayoutParams(p);
fab.hide;
并重新显示
fab = (FloatingActionButton) findViewById(R.id.fab);
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setAnchorId(View.NO_ID);
fab.setLayoutParams(p);
fab.show;
隐藏和显示浮动操作按钮的最简单方法是在 activity 中调用它。这也会自动正确地为您的 FAB 设置动画。
隐藏:
nameOfYourFAB.Hide();
显示:
nameOfYourFAB.Show();
你可以这样做:
fab.setEnabled(false);
fab.setClickable(false);
fab.setAlpha(0.0f);
这与 View.Gone
的行为类似
我正在尝试以编程方式隐藏我的 FloatingActionButton fabLocation
:
fabLocation.setVisibility(View.GONE)
但它不起作用。
如果我在我的 XML 布局中添加 android:visibility="gone"
,当我 运行 我的 activity 时 fabLocation
是隐藏的,但当我滚动时它会重新出现。
这是我的布局:
<?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"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="@color/colorOverlay"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/img_couverture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
android:src="@drawable/bg_navigation_drawer_header"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp" />
<View
android:background="@drawable/separator_orange_gradient"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:layout_width="match_parent"
android:layout_height="2dp"/>
<TextView
android:id="@+id/tv_history"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.RobotoLight" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:id="@+id/fab_location"
android:src="@drawable/ic_fab_location_24dp"
app:backgroundTint="@color/colorOrange"
app:layout_anchor="@id/appbar"
app:layout_anchorGravity="bottom|right|end" />
这是由于 app:layout_anchor
属性。在更改可见性之前,您必须先删除锚点:
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setAnchorId(View.NO_ID);
fab.setLayoutParams(p);
fab.setVisibility(View.GONE);
如果要显示隐藏FAB
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
...
</android.support.design.widget.AppBarLayout>
...
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:visibility="gone"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:clickable="true"/>
</android.support.design.widget.CoordinatorLayout>
和
CoordinatorLayout.LayoutParams p = new CoordinatorLayout.LayoutParams(CoordinatorLayout.LayoutParams.WRAP_CONTENT, CoordinatorLayout.LayoutParams.WRAP_CONTENT);
p.anchorGravity = Gravity.BOTTOM | Gravity.END;
p.setAnchorId(R.id.appbar);
p.setMargins(...);
fab.setLayoutParams(p);
fab.setVisibility(View.VISIBLE);
None 这些其他解决方案帮助了我 100%。我需要重复动画显示和隐藏(如 FAB.show()
和 hide()
),同时在可见时锚定到应用栏。
我每次展示它时都会创建新的 FAB,手动插入和锚定它,并根据支持库实现为其设置动画。这很恶心,但效果很好。
private void hidePlayButton(final FloatingActionButton fab) {
// Cancel any animation from the default behavior
fab.animate().cancel();
fab.animate()
.scaleX(0f)
.scaleY(0f)
.alpha(0f)
.setDuration(200)
.setInterpolator(new FastOutLinearInInterpolator())
.setListener(new Animator.AnimatorListener() {
@Override public void onAnimationStart(Animator animation) {}
@Override public void onAnimationEnd(Animator animation) {
coordinatorLayout.removeView(fab);
}
@Override public void onAnimationCancel(Animator animation) {}
@Override public void onAnimationRepeat(Animator animation) {}
});
}
private void showPlayButton() {
int fabSize = getResources().getDimensionPixelSize(R.dimen.fab_size);
int margin = getResources().getDimensionPixelSize(R.dimen.fab_margin);
final FloatingActionButton fab = new FloatingActionButton(getActivity());
fab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getActivity(), R.color.tint)));
fab.setImageDrawable(ContextCompat.getDrawable(getActivity(), R.drawable.play));
CoordinatorLayout.LayoutParams p = new CoordinatorLayout.LayoutParams(fabSize, fabSize);
p.rightMargin = p.leftMargin = p.bottomMargin = p.topMargin = margin;
p.anchorGravity = Gravity.BOTTOM | Gravity.END;
p.setAnchorId(R.id.appbar);
fab.setLayoutParams(p);
// Start from 1 pixel
fab.setAlpha(0f);
fab.setScaleX(0f);
fab.setScaleY(0f);
binding.coordinatorLayout.addView(fab);
fab.animate()
.alpha(1f)
.scaleX(1f)
.scaleY(1f)
.setDuration(200)
.setInterpolator(new FastOutLinearInInterpolator());
fab.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
hidePlayButton(fab);
// do action
}
});
}
简单代码:
public static void setVisibilityFab(FloatingActionButton fab, int visibility)
{
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setAnchorId(View.NO_ID);
fab.setLayoutParams(p);
if(visibility==View.GONE || visibility==View.INVISIBLE)
fab.setVisibility(View.GONE);
else
fab.setVisibility(View.VISIBLE);
}
经过一些回答后,我找到了解决我的问题的方法(当 fab 被隐藏时它可以处理动作!)。
首先我建议您将.setVisibility(View.GONE)
和.setVisibility(View.VISIBLE)
替换为.show()
和.hide()
方法。这些最后句柄也 actionMode
.
对我来说第二个问题是隐藏 fab 时也处理的操作,为了解决这个问题我做到了:
final CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams)floatingActionButton.getLayoutParams();
if (show){
p.setAnchorId(R.id.appBarLayout);
p.width = CoordinatorLayout.LayoutParams.WRAP_CONTENT;
p.height = CoordinatorLayout.LayoutParams.WRAP_CONTENT;
floatingActionButton.setLayoutParams(p);
floatingActionButton.show();
}else{
p.setAnchorId(View.NO_ID);
p.width = 0;
p.height = 0;
floatingActionButton.setLayoutParams(p);
floatingActionButton.hide();
}
我知道您的回答是关于如何使其适用于 gone
可见性,但如果您使用 invisible
而不是,您将不用担心,而且代码更少。
我通过使用布局边距将 FAB 放置在屏幕内或屏幕外来解决 show()/hide() 的缺点。示例:
CoordinatorLayout.LayoutParams p =
new CoordinatorLayout.LayoutParams(
CoordinatorLayout.LayoutParams.WRAP_CONTENT,
CoordinatorLayout.LayoutParams.WRAP_CONTENT);
p.gravity = Gravity.BOTTOM | Gravity.LEFT;
int fabMargin = (int)res.getDimension(R.dimen.fab_margin);
if( enabled ) {
p.setMargins(fabMargin,0,0,fabMargin);
}
else {
p.setMargins(-200,0,0,fabMargin);
}
mFab.setLayoutParams(p);
我用这个代码:
boolean mFabShouldBeShown;
FloatingActionButton.OnVisibilityChangedListener fabListener = new FloatingActionButton.OnVisibilityChangedListener() {
@Override
public void onShown(FloatingActionButton fab) {
super.onShown(fab);
if(!mFabShouldBeShown){
fab.hide();
}
}
@Override
public void onHidden(FloatingActionButton fab) {
super.onHidden(fab);
if(mFabShouldBeShown){
fab.show();
}
}
};
public void methodWhereFabIsHidden() {
mFabShouldBeShown = false;
mFloatingActionButton.hide(fabListener);
}
public void methodWhereFabIsShown() {
mFabShouldBeShown = true;
mFloatingActionButton.show(fabListener);
}
真正解决你问题的办法是subclass默认FloatingActionButton.Behavior
在它们的构造函数中调用setAutoHide(false)
,这样你就可以自己控制了。
请注意,我在下面谈论底部 sheets,但对于所有锚定的浮动操作按钮来说都是完全相同的问题,它确实回答了问题并且应该解决了问题不出所料。
或者,您可以覆盖自定义行为中的 boolean onDependentViewChanged(…)
方法,复制 FloatingActionButton.Behavior
class 中存在的 isBottomSheet(…)
静态方法,并且只调用 & return super 方法的值如果不是底部 sheet.
您可以通过这种方式进一步自定义默认行为,或者通过直接扩展香草 CoordinatorLayout.Behavior
class,您可以挑选代码从 FloatingActionButton.Behavior
class 如果需要的话。
这是我用来控制 FAB 可见性的代码:
/**
* Allows controlling the FAB visibility manually.
*/
@SuppressWarnings("unused")
public class FabManualHideBehavior extends FloatingActionButton.Behavior {
public FabManualHideBehavior() {
super();
setAutoHideEnabled(false);
}
public FabManualHideBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
setAutoHideEnabled(false);
}
}
我在 xml 中以这种方式将其应用到我的 FAB:
<android.support.design.widget.CoordinatorLayout
...>
...
<android.support.design.widget.FloatingActionButton
...
app:layout_anchor="@+id/bottom_sheet"
app:layout_anchorGravity="top|end"
app:layout_behavior="your.package.name.ui.behavior.FabManualHideBehavior"/>
</android.support.design.widget.CoordinatorLayout>
这是简单的解决方案
private var fabAnchorId: Int = View.NO_ID
private val fabParams: CoordinatorLayout.LayoutParams
get() = (fab.layoutParams as CoordinatorLayout.LayoutParams)
fun showFab() {
fabParams.anchorId = fabAnchorId
fabParams.gravity = Gravity.NO_GRAVITY
fab.show()
}
fun hideFab() {
fabParams.anchorId = View.NO_ID
fabParams.gravity = Gravity.END.or(Gravity.BOTTOM)
fab.hide()
}
在show/hide之前我们必须改变锚点和重力
锚定到 AppBarLayout 的 FloatingActionButtons 有一种特殊的关系,它们的可见性由 AppBarLayout 的滚动位置控制。
您可以通过 behavior_autoHide
属性关闭此功能:
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="..."
app:behavior_autoHide="false"/>
如果您愿意,您也可以通过编程方式执行此操作:
编辑:
fab.getBehavior() 不正确,使用 LayoutParams
getBehavior()
CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
FloatingActionButton.Behavior behavior = (FloatingActionButton.Behavior) lp.getBehavior();
if (behavior != null) {
behavior.setAutoHideEnabled(false);
} else {
behavior = new FloatingActionButton.Behavior();
behavior.setAutoHideEnabled(false);
lp.setBehavior(behavior);
}
我对发布的任何解决方案都不满意。有些只工作了一部分时间,而另一些只工作了 fab.setVisibility()
。虽然我知道这在技术上是原始问题所问的问题,但一些回复表示有兴趣使用 fab.hide()
,并且弄乱布局参数并不能完全解决问题的根源。
正如@ChrisBanes 所指出的,FloatingActionButton.Behavior
与 AppBarLayout
绑定是导致问题的原因。因此,与他的回答一样,您必须 setAutoHideEnabled(false)
才能禁用该功能。但是,如果您确实希望 FloatingActionButton
在手动调用 hide()
时自动隐藏 和 ,则此解决方案无济于事。
所以为了做到这一点;我只是在手动隐藏 Button
之前禁用自动隐藏功能,然后在手动显示 Button
:
private void hideFloatingActionButton(FloatingActionButton fab) {
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) fab.getLayoutParams();
FloatingActionButton.Behavior behavior =
(FloatingActionButton.Behavior) params.getBehavior();
if (behavior != null) {
behavior.setAutoHideEnabled(false);
}
fab.hide();
}
private void showFloatingActionButton(FloatingActionButton fab) {
fab.show();
CoordinatorLayout.LayoutParams params =
(CoordinatorLayout.LayoutParams) fab.getLayoutParams();
FloatingActionButton.Behavior behavior =
(FloatingActionButton.Behavior) params.getBehavior();
if (behavior != null) {
behavior.setAutoHideEnabled(true);
}
}
如果你想隐藏fab,你可以试试这个: fab.hide();
否则试试 fab.show();
享受。
FloatingActionButton layers = (FloatingActionButton) findViewById(R.id.layers);
layers.hide();
它适用于我,setVisibility
不适用于 FloatingActionButton
,因为它属于另一个没有 setVisibility
方法的 viewGroup
。
隐藏浮动按钮
fab = (FloatingActionButton) findViewById(R.id.fab);
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setAnchorId(View.NO_ID);
fab.setLayoutParams(p);
fab.hide;
并重新显示
fab = (FloatingActionButton) findViewById(R.id.fab);
CoordinatorLayout.LayoutParams p = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
p.setAnchorId(View.NO_ID);
fab.setLayoutParams(p);
fab.show;
隐藏和显示浮动操作按钮的最简单方法是在 activity 中调用它。这也会自动正确地为您的 FAB 设置动画。
隐藏:
nameOfYourFAB.Hide();
显示:
nameOfYourFAB.Show();
你可以这样做:
fab.setEnabled(false);
fab.setClickable(false);
fab.setAlpha(0.0f);
这与 View.Gone