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


14

私は2つの状態の間で行くべきボトムシートを持っている、STATE_COLLAPSEDそしてSTATE_EXPANDED それは崩壊だとき絶頂にする必要があります200dpし、拡張したとき、それはフルスクリーンになります。

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

isFitToContents = false
peekHeight = 200dp

下のシートで画面の半分を占めるhalfExpandedRatio場合、私はそうでなければ値を設定することを強いられSTATE_HALF_EXPANDEDます。

私はw /で働いています com.google.android.material:material:1.1.0-rc01

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

またはskipCollapsed=true、実際にを設定し、比率の観点から200 dpの意味を理解してSTATE_HALF_EXPANDED、のSTATE_EXPANDED代わりにSTATE_COLLAPSEDSTATE_EXPANDED


下のシートがどのように見えるかなどの詳細を提供してください。
UD ..

@UD ..この場合、ボトムシートのコンテンツは関連性がないと思います。これはより一般的な質問です。ボトムシートの状態の1つを無効にすることは可能ですか
Noa Drach '26

1
私の使用例では、設定halfExpandedRatio=0.25fpeekHeight = 200dpてから処理STATE_COLLAPSEDしてSTATE_HALF_EXPANDED、まるで同じ状態であるかのように問題を解決しているようです。他のアイデアがある場合に備えて、質問を開いたままにします。
Noa Drach

あなたはこのリンクをたどることができます、それはandroidhive.info/2017/12/android-working-with-bottom-sheet
UD

質問で設定された目的を満たしている場合は、必ずこれらの回答のいずれかを受け入れてください。
CommonsWare

回答:


3

半分の拡大比の値は、0と1の間にいくつかの値に設定する必要があります排他的なので、あまり自分のPEEK高さよりも「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して、「ハーフハイト」の問題を回避しながら指定できますか?ゼロ以外の拡張オフセットの要件はないので、それについて心配する必要はありません。

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

ここに画像の説明を入力してください

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>

あなたの最初の反応について-半分の拡大率を設定しても、一番下のシートの非常に細いヒントがまだ見えることがわかりました。とにかく、これは私が探している行動ではありません。「代替ソリューション」で説明したように、「ボトムシートはピークの高さと完全な高さの間で移行する必要があります」
Noa Drach

あなたの「代替ソリューション」は機能しているようで、私が必要としたソリューションです。私の最初のテストでは、使用する必要があることisFitToContents = falseisFitToContents = true
わかりました

@NoaDrach下部シートが非表示の場合、下部シートのオフセットの計算方法により、最低1pxが下部に表示されます。シートが非表示になるとは思っていませんでしたが、1pxが表示されているためsheetBehavior.state = BottomSheetBehavior.STATE_HIDDEN、半展開状態になるとシートを強制的に非表示にできますが、少し複雑になります。代替ソリューションの方が優れています。
Cheticamp

2

ここに画像の説明を入力してください

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

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>

非常に良い答え...私の日を救った
1

1

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


素敵なアイデアは、私の場合、私はに状態を設定しますSTATE_COLLAPSEDといませんSTATE_HIDDEN。しかし、私はそれを実装しようとしましたが、からSTATE_HALF_EXPANDEDへの移行STATE_COLLAPSEDは不格好に感じます。状態間の遷移は、あなたがで停止ボトムシートを参照して、アニメーション化されSTATE_HALF_EXPANDEDた後、それがに移動STATE_COLLAPSED
ノアDrach

これをhalfExpandedRatioの0と組み合わせることができますか?
Ridcully

@Ridcully-ここに2つの問題-1. halfExpandedRatioは0より大きい必要があります2.非常に低い値に設定すると、折りたたまれた状態にスナップされる前に、ほぼ完全に最小化されます(半分が展開された状態)。私はこの提案と私の解決策halfExpandedState=0.25fb / c を組み合わせることを考えましたが、状態間の遷移はこれほど明白ではありません。しかし、私は私がすでに持っているものに比べて大きな変化になることはよく分からない
ノアDrach

1

レイアウトを高さの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

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


0

いろいろな方法を試しましたが、完璧に機能するテクニックはありませんでした。カスタムロジックに基づいてイベントをインターセプトし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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.