web-dev-qa-db-ja.com

Android-下部シートのSTATE_HALF_EXPANDED状態を無効にする方法

2つの状態STATE_COLLAPSEDSTATE_EXPANDEDの間を移動する下部のシートがあります。折りたたまれると、高さが200dpになり、展開するとフルスクリーンになります。

だから私はBottomSheetBehaviorを設定しています

isFitToContents = false
peekHeight = 200dp

halfExpandedRatioに値を設定する必要があります。そうしないと、STATE_HALF_EXPANDEDで下部シートが画面の半分を占めるようになります。

com.google.Android.material:material:1.1.0-rc01を使用して作業しています

STATE_HALF_EXPANDED状態を無効にする方法はありますか?

または、実際にskipCollapsed=trueを設定して、200dpの意味を比率で把握し、STATE_HALF_EXPANDEDSTATE_EXPANDEDの代わりにSTATE_COLLAPSEDSTATE_EXPANDEDを使用する必要があります。

14
Noa Drach

半分に拡大された比率の値は、0と1の間の値exclusiveに設定する必要があるため、この値を、ピークの高さよりも確実に低い非常に低い数値に設定します、「0.0001f」と言います。この値では、_STATE_HALF_EXPANDED_の状態も表示されません。状態は_STATE_EXPANDED_と_STATE_COLLAPSED_の間で変動します。


代替ソリューション

上記のソリューションは機能し、_STATE_HALF_EXPANDED_状態を効果的に無効にしますが、ハック(IMO)であり、将来的には機能しなくなる可能性があります。たとえば、ピークの高さと完全な高さの間のどこかにある半分に拡大された比率に適切な値が適用されている場合はどうなりますか?それは問題だろう。

OPで述べられている要件は、ボトムシートがピークの高さとフルの高さの間で移行することです。ピークの高さに問題はありませんが、OPは_isFitToContents = false_を指定して完全な高さにします。 (私は彼のボトムシートが利用可能なスペースよりも短いかもしれないと思います。)

残念ながら、_isFitToContents == false_が追加されると、OPが回避したいと考える問題である「ハーフハイト」動作が追加されます。

「ハーフハイト」動作に加えて、「拡張オフセット」という別の動作が導入されています。展開されたオフセットは、下部シートがフルスクリーンからどれだけ下に停止するかを指定します。たとえば、値が_100f_の場合、完全に展開すると、下のシートの上部に_100px_の枠が残ります。拡張オフセットのデフォルトはゼロです。

上記の動作以外に_isFitToContents == false_が引き起こす動作は知りません。

したがって、これらの要件を前提として、_isFitToContents == true_を指定して「高さの半分」の問題を回避しながら、ピークの高さと完全な高さの間を移動するボトムシートを作成できますか?ゼロ以外の拡張オフセットの要件はないので、それについて心配する必要はありません。

以下は、右のボトムシート構造でこれらの要件を満たすことができることを示す短いデモアプリです。

enter image description here

MainActivity5.kt

_class MainActivity5 : BaseActivity() {  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  
        setContentView(R.layout.activity_main5)  

        val bottomSheet = findViewById<LinearLayout>(R.id.bottom_sheet)  
        val sheetBehavior: BottomSheetBehavior<LinearLayout> = BottomSheetBehavior.from(bottomSheet)  
        sheetBehavior.isFitToContents = true // the default  
  sheetBehavior.peekHeight = 200  

  // Log the states the bottom sheet passes through.  
  sheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {  
            override fun onStateChanged(bottomSheet: View, newState: Int) {  
                Log.d("MainActivity", "<<<< $newState = ${translateSheetState(newState)}")  
            }  

            override fun onSlide(bottomSheet: View, slideOffset: Float) {}  
        })  
    }  
}
_

BaseActivity.kt

_open class BaseActivity : AppCompatActivity() {  

    protected fun translateSheetState(state: Int): String {  
        return when (state) {  
            BottomSheetBehavior.STATE_COLLAPSED -> "STATE_COLLAPSED"  
  BottomSheetBehavior.STATE_DRAGGING -> "STATE_DRAGGING"  
  BottomSheetBehavior.STATE_EXPANDED -> "STATE_EXPANDED"  
  BottomSheetBehavior.STATE_HALF_EXPANDED -> "STATE_HALF_EXPANDED"  
  BottomSheetBehavior.STATE_HIDDEN -> "STATE_HIDDEN"  
  BottomSheetBehavior.STATE_SETTLING -> "STATE_SETTLING"  
  else -> "Unknown state: $state"  
  }  
    }  
}
_

activity_main5.xml

_<androidx.coordinatorlayout.widget.CoordinatorLayout 
    Android:id="@+id/main_content"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <LinearLayout
        Android:id="@+id/bottom_sheet"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="@Android:color/holo_orange_light"
        Android:orientation="vertical"
        Android:scrollbars="none"
        app:layout_behavior="@string/bottom_sheet_behavior">

        <TextView
            Android:id="@+id/tv"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:padding="16dp"
            Android:text="@string/short_text"
            Android:textSize="16sp" />

    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
_

下部のシートが長い場合は、次の構造でスクロールします。

activity_main6.xml

_<androidx.coordinatorlayout.widget.CoordinatorLayout 
    Android:id="@+id/main_content"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <LinearLayout
        Android:id="@+id/bottom_sheet"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="@Android:color/holo_orange_light"
        Android:orientation="vertical"
        Android:scrollbars="none"
        app:layout_behavior="@string/bottom_sheet_behavior">

        <androidx.core.widget.NestedScrollView
            Android:layout_width="match_parent"
            Android:layout_height="match_parent">

            <TextView
                Android:id="@+id/tv"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:padding="16dp"
                Android:text="@string/long_text"
                Android:textSize="16sp" />
        </androidx.core.widget.NestedScrollView>
    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
_
3
Cheticamp

enter image description here

画像のように上記を試してみたい場合は、以下のコードに従ってください。

public class CollectionsBottomSheet extends BottomSheetDialogFragment {
    private BottomSheetBehavior mBehavior;


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
        View view = View.inflate(getContext(), R.layout.collections_layout, null);
        LinearLayout linearLayout = view.findViewById(R.id.root);
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) linearLayout.getLayoutParams();
        params.height = getScreenHeight();
        linearLayout.setLayoutParams(params);
        dialog.setContentView(view);
        mBehavior = BottomSheetBehavior.from((View) view.getParent());
        return dialog;

    }

    @Override
    public void onStart() {
        super.onStart();
        mBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
    }

    public static int getScreenHeight() {
        return Resources.getSystem().getDisplayMetrics().heightPixels;
    }
}



xml 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/bottom_sheet"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="@color/white"
    Android:fitsSystemWindows="true">


    <LinearLayout
        Android:id="@+id/root"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical">

        <LinearLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:gravity="center_vertical"
            Android:orientation="horizontal">

            <TextView
                Android:id="@+id/filter_title"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:drawableStart="@drawable/ic_cancel"
                Android:drawableLeft="@drawable/ic_cancel"
                Android:drawablePadding="30dp"
                Android:gravity="center_vertical"
                Android:padding="12dp"
                Android:text="Filters"
                Android:textColor="@color/black"
                Android:textSize="18sp" />

            <View
                Android:layout_width="0dp"
                Android:layout_height="0dp"
                Android:layout_weight="1" />

            <TextView
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:layout_marginEnd="10dp"
                Android:layout_marginRight="10dp"
                Android:padding="5dp"
                Android:text="Reset ALL"
                Android:textColor="#6f6f6f"
                Android:textSize="12sp" />

        </LinearLayout>

        <View
            Android:layout_width="match_parent"
            Android:layout_height="1dp"
            Android:background="#d8dbdb" />

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="@drawable/sort_background"
            Android:drawableStart="@drawable/ic_star"
            Android:drawableLeft="@drawable/ic_star"
            Android:drawablePadding="15dp"
            Android:padding="15dp"
            Android:text="GUEST RATINGS"
            Android:textColor="#6f6f6f"
            Android:textSize="16sp" />

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="@drawable/sort_background"
            Android:drawableStart="@drawable/ic_money"
            Android:drawableLeft="@drawable/ic_money"
            Android:drawablePadding="15dp"
            Android:padding="15dp"
            Android:text="PRICE RANGE"
            Android:textColor="#6f6f6f"
            Android:textSize="16sp" />

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="@drawable/sort_background"
            Android:drawableStart="@drawable/ic_loan"
            Android:drawableLeft="@drawable/ic_star"
            Android:drawablePadding="15dp"
            Android:padding="15dp"
            Android:text="PAY AT HOTEL"
            Android:textColor="#6f6f6f"
            Android:textSize="16sp" />

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="@drawable/sort_background"
            Android:drawableStart="@drawable/ic_folder"
            Android:drawableLeft="@drawable/ic_folder"
            Android:drawablePadding="15dp"
            Android:padding="15dp"
            Android:text="COLLECTIONS"
            Android:textColor="#6f6f6f"
            Android:textSize="16sp" />

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="@drawable/sort_background"
            Android:drawableStart="@drawable/ic_perm_identity_black_24dp"
            Android:drawableLeft="@drawable/ic_perm_identity_black_24dp"
            Android:drawablePadding="15dp"
            Android:padding="15dp"
            Android:text="FACILITIES"
            Android:textColor="#6f6f6f"
            Android:textSize="16sp" />

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="@drawable/sort_background"
            Android:drawableStart="@drawable/ic_apartment"
            Android:drawableLeft="@drawable/ic_apartment"
            Android:drawablePadding="15dp"
            Android:padding="15dp"
            Android:text="CATEGORIES"
            Android:textColor="#6f6f6f"
            Android:textSize="16sp" />

        <TextView
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="@drawable/sort_background"
            Android:drawableStart="@drawable/ic_hotel_building"
            Android:drawableLeft="@drawable/ic_hotel_building"
            Android:drawablePadding="15dp"
            Android:padding="15dp"
            Android:text="ACCOMMODATION TYPE"
            Android:textColor="#6f6f6f"
            Android:textSize="16sp" />

    </LinearLayout>


</LinearLayout>
2
UD..

レイアウトを高さの3分の1にする必要がある同様の使用例があります。私は以下を試してみましたが、うまくいきました。

<androidx.coordinatorlayout.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/bottom_sheet_container"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="@color/grey"
    Android:clickable="true">

    <LinearLayout
        Android:id="@+id/bottom_sheet"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="@drawable/rounded_bottom_sheet_background"
        Android:orientation="vertical"
        app:layout_behavior="com.google.Android.material.bottomsheet.BottomSheetBehavior">

        <androidx.recyclerview.widget.RecyclerView
            Android:id="@+id/recycler"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent" />
    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

これらを動的に変更する必要があったので、下のシートに次のように設定しましたが、xmlでもこれを行うことができます。

bottomSheet.setPeekHeight(200);// 200px
bottomSheet.setHideable(false);

非表示にするために、次の関数を使用してフラグメントにアニメーションを追加しました。

fragmentTransaction.setCustomAnimations(
                    R.anim.fade_in,
                    R.anim.fade_out,
                    R.anim.fade_in,
                    R.anim.fade_out)

お役に立てれば

1
Saurabh

addBottomSheetCallbackBottomSheetBehaviorを設定してみてください。_STATE_HALF_EXPANDED_状態を検出したら、setState(STATE_HIDDEN)を呼び出して、下のシートが中間状態に到達しようとするたびに、閉じます。

1
marmor

BottomSheetBehavior.setHalfExpandedRatio(0f) を設定してみてください。 。setState() を使用して明示的に状態を設定しない限り、STATE_HALF_EXPANDEDに影響する他の多くのものはありません。 CoordinatorLayout.Behavior<View>を拡張し、STATE_HALF_EXPANDEDを持たないカスタムBehaviorを作成することも可能です。例えば。 CoordinatorLayout Behaviorsですべてをインターセプト

1
Martin Zeitler

いろいろな方法を試しましたが、完璧に機能するテクニックはありませんでした。カスタムロジックに基づいて_BottomSheetBehavior.BottomSheetCallback {}_でイベントをインターセプトしてdismiss()を呼び出しましたが、ジャークが発生しました。

それで、ついに、私のBottomSheetDialogFragment_bottomSheetBehavior.isDraggable = false_を追加しました。これにより、タッチによって下のシートのドラッグが発生しました。そして、私は自分でダイアログの却下を処理しました。とにかく、空の領域のダイアログでは閉じられます。

一番下のシートはまだアニメーションで拡大していることに注意してください。それは本当に素晴らしいです!

fun onCreateDialog(savedInstanceState:Bundle?):Dialogをオーバーライドします{val dialog = super.onCreateDialog(savedInstanceState)

_    dialog.setOnShowListener {
        val bottomSheetDialog = it as BottomSheetDialog
        val bottomSheet =
            bottomSheetDialog.findViewById<View>(com.google.Android.material.R.id.design_bottom_sheet)
                ?: return@setOnShowListener

        //Making background to transparent to avoid white background to given space margin.
        bottomSheet.setBackgroundColor(ContextCompat.getColor(context!!, R.color.transparent))

        val inflatedView = fragmentProfileDialogBinding.root
        val parent = inflatedView.parent as View

        val bottomSheetBehavior = BottomSheetBehavior.from(parent)
        bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
        bottomSheetBehavior.isDraggable = false
    }

    return dialog
}
_
0
Rahul Rastogi