I am trying to hide my FloatingActionButton fabLocation
programmatically with :
fabLocation.setVisibility(View.GONE)
but it do
FloatingActionButton layers = (FloatingActionButton) findViewById(R.id.layers);
layers.hide();
It works for me, setVisibility
doesn't work for FloatingActionButton
as it belongs to another viewGroup
that doesn't have setVisibility
method.
The real solution for your problem is to subclass default FloatingActionButton.Behavior
to call setAutoHide(false)
in their constructors, so you can control it yourself.
Note that I talk about bottom sheets below, but it is exactly the same problem for all anchored Floating Action Buttons, and it does respond to the question and should solve the problem as expected.
Alternatively, you can override the boolean onDependentViewChanged(…)
method from your custom Behavior, copy the isBottomSheet(…)
static method present in the FloatingActionButton.Behavior
class, and only call & return the value of the super method if it's not a bottom sheet.
You can further customize the default behavior this way, or by extending the vanilla CoordinatorLayout.Behavior
class directly, and you can cherry pick code to copy paste from the FloatingActionButton.Behavior
class if needed.
Here's the code I used to control back the FAB visibility:
/**
* 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);
}
}
And I applied it to my FAB in xml this way:
<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>
I wasn't completely happy with any of the solutions posted. Some only worked part of the time, while others only worked for fab.setVisibility()
. While I know this is technically what the original question asked, a few responses expressed interest in using fab.hide()
, and messing with the layout parameters doesn't exactly get to the root of the issue.
As pointed out by @ChrisBanes, the FloatingActionButton.Behavior
being tied to the AppBarLayout
is what causes the issue. So, as with his answer, you have to setAutoHideEnabled(false)
to disable that functionality. But this solution doesn't help if you actually want the FloatingActionButton
to hide automatically and when you call hide()
manually.
So in order to do this; I simply disable the auto-hide functionality before I manually hide the Button
, then re-enable the functionality after I manually show the 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);
}
}
After some answers around, I founded the solution for my problem(also when the fab is hidden it can handle action!).
First of all I suggest you to replace .setVisibility(View.GONE)
and .setVisibility(View.VISIBLE)
with the methods .show()
and .hide()
. These last handle also actionMode
.
The second problem for me was the action also handled when the fab was hidden, for resolve this I made it:
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();
}
I know that you answer is about how to make it work for gone
visibility but if you use invisible
instead you will have no worries about that and is less code.
FloatingActionButtons anchored to AppBarLayouts have a special relationship where their visibility is controlled by the scroll position of the AppBarLayout.
You can turn this off via the behavior_autoHide
attribute:
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="..."
app:behavior_autoHide="false"/>
You can also do this programmatically if you wish:
EDIT:
fab.getBehavior() was not correct, use getBehavior()
from its LayoutParams
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);
}