私はFloatingActionButton fabLocation
をプログラムで非表示にしようとしています:
fabLocation.setVisibility(View.GONE)
しかし、それは機能しません。
XMLレイアウトにAndroid:visibility="gone"
を追加すると、アクティビティを実行すると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);
AppBarLayoutsに固定された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が指摘したように、AppBarLayout
に結び付けられている_FloatingActionButton.Behavior
_が問題の原因です。したがって、彼の答えと同様に、その機能を無効にするにはsetAutoHideEnabled(false)
する必要があります。しかし、実際にFloatingActionButton
を自動的に非表示にしたい場合、このソリューションは役に立ちませんandhide()
を手動で呼び出したとき。
したがって、これを行うために;手動で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);
}
}
_
フローティングアクションバーを非表示および表示する最も単純な方法は、アクティビティでこれを呼び出すことです。
隠す:
nameOfYourFAB.Hide();
公演:
nameOfYourFAB.Show();
FloatingActionButton layers = (FloatingActionButton) findViewById(R.id.layers);
layers.hide();
setVisibility
メソッドを持たない別のFloatingActionButton
に属しているため、viewGroup
はsetVisibility
に対して機能しません。
非表示の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);
いくつかの回答をした後、問題の解決策を見つけました(ファブが非表示になっている場合でもアクションを処理できます!)。
まず、.setVisibility(View.GONE)
および.setVisibility(View.VISIBLE)
を.show()
および.hide()
メソッドに置き換えることをお勧めします。これらの最後のハンドルもactionMode
です。
私にとって2番目の問題は、ファブが非表示になったときにもアクションが処理されることでした。これを解決するために私はそれを作りました:
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();
}
フローティングボタンを非表示にするには
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;
Fabを非表示にする場合は、次を試してください:fab.hide();
それ以外の場合は、fab.show()を試してください。
楽しい。
あなたの問題の本当の解決策は、コンストラクタでsetAutoHide(false)
を呼び出すためにデフォルトの_FloatingActionButton.Behavior
_をサブクラス化することです。それで、あなたはそれを自分で制御できます。
下のシートについて説明しますが、すべての固定フローティングアクションボタンでまったく同じ問題であり、質問に応答するため、予想どおりに問題を解決する必要があります。
または、カスタム動作からboolean onDependentViewChanged(…)
メソッドをオーバーライドし、_FloatingActionButton.Behavior
_クラスにあるisBottomSheet(…)
静的メソッドをコピーし、superの値のみを呼び出して返すことができますボトムシートでない場合のメソッド。
この方法でデフォルトの動作をさらにカスタマイズしたり、Vanilla _CoordinatorLayout.Behavior
_クラスを直接拡張したり、必要に応じて_FloatingActionButton.Behavior
_クラスから貼り付けてコピーするコードを選択できます。
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()
}
表示/非表示の前に、アンカーと重力を変更する必要があります
これらの他のソリューションはどれも私を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
}
});
}
私はこのコードを使用します:
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);
}
レイアウトマージンを使用して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);
簡単なコード:
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);
}
あなたが答えるのはgone
可視性のためにそれを動作させる方法に関することですが、代わりにinvisible
を使用する場合、それについて心配する必要はなく、コードも少なくなります。