web-dev-qa-db-ja.com

Googleマップのボトムシートの3段階の動作を模倣する方法

バックグラウンド

Googleマップで検索結果のボトムシートを表示するのと同様に動作するUIを作成するように割り当てられています。

次の3つのフェーズがあります。

  1. ボトムコンテンツ。上部の領域は引き続きタッチ可能で、下部には何もスクロールしません
  2. 全画面コンテンツ。上部領域には大きなヘッダーがあります。
  3. 全画面コンテンツ。上部領域にはツールバーのみがあります。

Googleマップで私が話していることは次のとおりです。

Enter image description here

問題

つまり、ボトムシートはまだデザインライブラリの一部ではありません(要求されたものの、 here )。

それだけでなく、UIは非常に複雑に見えるため、複数のフェーズでツールバーを処理する必要があります。

私が試したこと

ボトムシート用の優れた(十分な)ライブラリ( here )を見つけ、そのフラグメントサンプルにコンテンツを追加して、ほぼ同じビューを得るマテリアルデザインサンプル( here など)に示すように、フェーズ2 + 3を処理するCollapsingToolbarLayoutを用意します。

私が作成しているアプリでは、スクロールしながらアイコンも移動する必要がありますが、残りで成功した場合、これは簡単なはずです。コードは次のとおりです。

fragment_my.xml

<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout
    Android:id="@+id/main_content"
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <Android.support.design.widget.AppBarLayout
        Android:id="@+id/appbar"
        Android:layout_width="match_parent"
        Android:layout_height="@dimen/detail_backdrop_height"

        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"

            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <ImageView
                Android:id="@+id/backdrop"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:scaleType="centerCrop"
                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"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:orientation="vertical"
            Android:paddingTop="24dp">

            <Android.support.v7.widget.CardView
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_margin="@dimen/card_margin">

                <LinearLayout
                    style="@style/Widget.CardContent"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content">

                    <TextView
                        Android:layout_width="match_parent"
                        Android:layout_height="wrap_content"
                        Android:text="Info"
                        Android:textAppearance="@style/TextAppearance.AppCompat.Title"/>

                    <TextView
                        Android:layout_width="match_parent"
                        Android:layout_height="wrap_content"
                        Android:text="@string/cheese_ipsum"/>
                </LinearLayout>
            </Android.support.v7.widget.CardView>

            <Android.support.v7.widget.CardView
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_marginBottom="@dimen/card_margin"
                Android:layout_marginLeft="@dimen/card_margin"
                Android:layout_marginRight="@dimen/card_margin">

                <LinearLayout
                    style="@style/Widget.CardContent"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content">

                    <TextView
                        Android:layout_width="match_parent"
                        Android:layout_height="wrap_content"
                        Android:text="Friends"
                        Android:textAppearance="@style/TextAppearance.AppCompat.Title"/>

                    <TextView
                        Android:layout_width="match_parent"
                        Android:layout_height="wrap_content"
                        Android:text="@string/cheese_ipsum"/>
                </LinearLayout>
            </Android.support.v7.widget.CardView>

            <Android.support.v7.widget.CardView
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:layout_marginBottom="@dimen/card_margin"
                Android:layout_marginLeft="@dimen/card_margin"
                Android:layout_marginRight="@dimen/card_margin">

                <LinearLayout
                    style="@style/Widget.CardContent"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content">

                    <TextView
                        Android:layout_width="match_parent"
                        Android:layout_height="wrap_content"
                        Android:text="Related"
                        Android:textAppearance="@style/TextAppearance.AppCompat.Title"/>

                    <TextView
                        Android:layout_width="match_parent"
                        Android:layout_height="wrap_content"
                        Android:text="@string/cheese_ipsum"/>
                </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="@dimen/fab_margin"
        Android:clickable="true"
        Android:src="@Android:drawable/ic_menu_send"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"/>

</Android.support.design.widget.CoordinatorLayout>

MyFragment.Java

public class MyFragment extends BottomSheetFragment {

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.fragment_my, container, false);
        view.setMinimumHeight(getResources().getDisplayMetrics().heightPixels);
        CollapsingToolbarLayout collapsingToolbar = (CollapsingToolbarLayout) view.findViewById(R.id.collapsing_toolbar);
        collapsingToolbar.setTitle("AAA");
        final Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
        final AppCompatActivity activity = (AppCompatActivity) getActivity();
        activity.setSupportActionBar(toolbar);
        activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        //toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                NavUtils.navigateUpFromSameTask(getActivity());
            }
        });
        final ImageView imageView = (ImageView) view.findViewById(R.id.backdrop);

        Glide.with(this).load(R.drawable.cheese_1).centerCrop().into(imageView);
        return view;
    }
}

BottomSheetFragmentActivity.Java

public final class BottomSheetFragmentActivity extends AppCompatActivity {

    protected BottomSheetLayout bottomSheetLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bottom_sheet_fragment);
        bottomSheetLayout = (BottomSheetLayout) findViewById(R.id.bottomsheet);
        findViewById(R.id.bottomsheet_fragment_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new MyFragment().show(getSupportFragmentManager(), R.id.bottomsheet);
            }
        });
        bottomSheetLayout.setShouldDimContentView(false);
        bottomSheetLayout.setPeekOnDismiss(true);
        bottomSheetLayout.setPeekSheetTranslation(200);
        bottomSheetLayout.setInterceptContentTouch(false);
        bottomSheetLayout.setDefaultViewTransformer(new BaseViewTransformer() {
            @Override
            public void transformView(final float translation, final float maxTranslation, final float peekedTranslation, final BottomSheetLayout parent, final View view) {
                Log.d("AppLog", "translation:" + translation + " maxTranslation:" + maxTranslation + " peekedTranslation:" + peekedTranslation);
            }
        });
    }
}

それはほとんどうまくいきます。唯一の問題は、#3から#2に戻ることです。

enter image description here

質問

コードの何が問題になっていますか?必要な動作を実現するために何ができますか?

105

:下部の編集を読む


OK、それを行う方法を見つけましたが、ボトムシートがappBarLayoutの状態(拡張されているかどうか)を認識し、スクロールアップを無視するように、複数のクラスのコードを変更する必要がありました展開されない:

BottomSheetLayout.Java

追加されたフィールド:

private AppBarLayout mAppBarLayout;
private OnOffsetChangedListener mOnOffsetChangedListener;
private int mAppBarLayoutOffset;

init()-これを追加しました:

    mOnOffsetChangedListener = new OnOffsetChangedListener() {
        @Override
        public void onOffsetChanged(final AppBarLayout appBarLayout, final int verticalOffset) {
            mAppBarLayoutOffset = verticalOffset;
        }
    };

AppBarLayoutを設定する機能が追加されました。

public void setAppBarLayout(final AppBarLayout appBarLayout) {
    if (mAppBarLayout == appBarLayout)
        return;
    if (mAppBarLayout != null)
        mAppBarLayout.removeOnOffsetChangedListener(mOnOffsetChangedListener);
    mAppBarLayout = appBarLayout;
    mAppBarLayout.addOnOffsetChangedListener(mOnOffsetChangedListener);
}

onDetachedFromWindow()-これを追加しました:

    if (mAppBarLayout != null)
        mAppBarLayout.removeOnOffsetChangedListener(mOnOffsetChangedListener);

onTouchEvent()-これを追加しました:

      ...
      if (bottomSheetOwnsTouch) {
        if (state == State.EXPANDED && scrollingDown && mAppBarLayout != null && mAppBarLayoutOffset != 0) {
            event.offsetLocation(0, sheetTranslation - getHeight());
            getSheetView().dispatchTouchEvent(event);
            return true;
        }
      ...

これらが主な変更点でした。次に、それらを設定するものについて:

MyFragment.Java

onCreateView()-これを追加しました:

    mBottomSheetLayout.setAppBarLayout((AppBarLayout) view.findViewById(R.id.appbar));

この機能も追加しました。

 public void setBottomSheetLayout(final BottomSheetLayout bottomSheetLayout) {
    mBottomSheetLayout = bottomSheetLayout;
}

これが、アクティビティがappBarLayoutについてフラグメントに伝える方法です。

            final MyFragment myFragment = new MyFragment();
            myFragment.setBottomSheetLayout(bottomSheetLayout);
            myFragment.show(getSupportFragmentManager(), R.id.bottomsheet);

プロジェクトがGitHubで利用可能になりました:

https://github.com/AndroidDeveloperLB/ThreePhasesBottomSheet

バグがないことを願っています。


残念ながら、このソリューションにはバグがあるため、この回答を正しいものとしてマークしません。

  1. Android 6以降でのみ機能します。他のケースでは、表示するたびに、ボトムシートがほんの少しの間展開されるという奇妙な動作をします。
  2. 向きを変更してもスクロールの状態はまったく保存されないため、無効にしました。
  3. ボトムシートのコンテンツが折りたたまれた状態で(下部で)スクロールできるというまれな問題
  4. 以前にキーボードが表示されていた場合、覗き見しようとしたときに下のシートがフルスクリーンになることがあります。

誰かがそれを手伝うことができるならば、してください。


問題#1では、ボトムシートがまだ覗いていないときに可視性をINVISIBLEに設定して修正を追加しようとしましたが、特にキーボードが表示されている場合は常に動作しません。


問題#1では、使用する任意のビュー(FrameLayoutを使用)でCoordinatorLayoutを(「fragment_my.xml」で)ラップするだけで修正する方法を見つけました。また、フルサイズのビューをそれ(私は単に "View"を置く)として:

<FrameLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">
    <!--This full sized view, together with the FrameLayout above, are used to handle some weird UI issues on pre-Android-6 -->
    <View
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"/>

    <...CollapsingToolbarLayout 
    ...

CoordinatorLayoutがビューであるとき、おそらくbottomSheetを混乱させました。私はプロジェクトを更新しましたが、それでも、より良いソリューションを得る方法があれば、それについて知りたいです。


ここ数か月で、Googleは独自のbottomSheetクラスを公開しましたが、多くの問題があることがわかったので、試してさえいません。

18

BIG UPDATE

同じトピックについて4つか5つの質問がありましたが、要件は異なりますが、それらすべてに回答しようとしましたが、非礼儀な管理者がそれらを削除/クローズし、それぞれのチケットを作成して、 「コピーペースト」は避けてください。Googleマップのような完全な動作を取得する方法に関するすべての説明が記載されている full answer へのリンクを提供します。


質問に答える

Googleマップのボトムシートの3段階の動作を模倣する方法

サポートライブラリ23.x.x +を使用すると、デフォルトのBottomSheetBehaviorを変更して、次の手順で統計をもう1つ追加できます。

  1. Javaクラスを作成し、CoordinatorLayout.Behavior<V>から拡張します
  2. デフォルトのBottomSheetBehaviorファイルから新しいコードにコードを貼り付けます。
  3. メソッドclampViewPositionVerticalを次のコードで変更します。

    @Override
    public int clampViewPositionVertical(View child, int top, int dy) {
        return constrain(top, mMinOffset, mHideable ? mParentHeight : mMaxOffset);
    }
    int constrain(int amount, int low, int high) {
        return amount < low ? low : (amount > high ? high : amount);
    }
    
  4. 新しい状態を追加します。

    public static final int STATE_ANCHOR_POINT = X;
    
  5. 次のメソッドを変更します:onLayoutChildonStopNestedScrollBottomSheetBehavior<V> from(V view)およびsetState(オプション)

これらの変更されたメソッドと サンプルプロジェクトへのリンク を追加します。

そして、それは次のようになります:
CustomBottomSheetBehavior

15
MiguelHincapieC

これを試しましたか? http://Android-developers.blogspot.in/2016/02/Android-support-library-232.html?m=1 ここでは、ボトムシートレイアウトの動作を指定することができると述べています。

UPDATE:

基本的にリンク状態

BottomSheetBehaviorをCoordinatorLayoutの子ビューにアタッチする(つまり、app:layout_behavior = "Android.support.design.widget.BottomSheetBehavior"を追加する)ことにより、5つの状態間を遷移する適切なタッチ検出を自動的に取得します。

STATE_COLLAPSED: this collapsed state is the default and shows just a portion of the layout along the bottom. The height can be controlled with the app:behavior_peekHeight attribute (defaults to 0)
STATE_DRAGGING: the intermediate state while the user is directly dragging the bottom sheet up or down
STATE_SETTLING: that brief time between when the View is released and settling into its final position
STATE_EXPANDED: the fully expanded state of the bottom sheet, where either the whole bottom sheet is visible (if its height is less than the containing CoordinatorLayout) or the entire CoordinatorLayout is filled
STATE_HIDDEN: disabled by default (and enabled with the app:behavior_hideable attribute), enabling this allows users to swipe down on the bottom sheet to completely hide the bottom sheet
Keep in mind that scrolling containers in your bottom sheet must support nested scrolling (for example, NestedScrollView, RecyclerView, or ListView/ScrollView on API 21+).

状態変化のコールバックを受け取りたい場合は、BottomSheetCallbackを追加できます:

// The View with the BottomSheetBehavior  
 View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);  
 BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);  
 behavior.setBottomSheetCallback(new BottomSheetCallback() {  
    @Override  
    public void onStateChanged(@NonNull View bottomSheet, int newState) {  
      // React to state change  
    }  
      @Override  
      public void onSlide(@NonNull View bottomSheet, float slideOffset) {  
       // React to dragging events  
   }  
 });  

BottomSheetBehaviorは永続的なボトムシートケースをキャプチャしますが、このリリースではモーダルボトムシートのユースケースを満たすためにBottomSheetDialogとBottomSheetDialogFragmentも提供します。 AppCompatDialogまたはAppCompatDialogFragmentを対応するボトムシートに置き換えるだけで、ダイアログをボトムシートとしてスタイル設定できます。

0
Vaibhav Sharma

また、Googleマップで見つかった結果のボトムシートを表示する方法と同様のビューを実装する必要がありました。

私の外観は次のとおりです。

Peek view

Expand view scrolled to top

Expand view scrolled to bottom

最初に、ヘッダーとスクロール可能なコンテンツを含むボトムシートを定義しましたが、wrap_contentを指定していても、layout_heightはヘッダーとスクロール可能なコンテンツのどちらのコンテンツもラップしていないようです。

LinearLayoutの子レイアウト(およびその子)にConstraintLayoutの代わりにCoordinatorLayoutを使用すると、この問題はなくなりました。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        Android:id="@+id/buttonPeek"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Peek"
        app:layout_constraintEnd_toStartOf="@+id/buttonExpand"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        Android:id="@+id/buttonExpand"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Expand"
        app:layout_constraintEnd_toStartOf="@+id/buttonClose"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/buttonPeek"
        app:layout_constraintTop_toTopOf="@+id/buttonPeek" />

    <Button
        Android:id="@+id/buttonClose"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Close"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/buttonExpand"
        app:layout_constraintTop_toTopOf="@+id/buttonExpand" />

    <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/layout_coordinator"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <LinearLayout
            Android:id="@+id/layout_coordinator_child"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:orientation="vertical"
            app:behavior_hideable="true"
            app:layout_behavior="@string/bottom_sheet_behavior">

            <LinearLayout
                Android:id="@+id/layout_bottom_sheet_header"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:background="#FFFF0000"
                Android:orientation="vertical" >

                <TextView
                    Android:id="@+id/headerTextView_a"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:text="a" />

                <TextView
                Android:id="@+id/headerTextView_b"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="b" />

                <TextView
                Android:id="@+id/headerTextView_c"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="c" />

                <TextView
                Android:id="@+id/headerTextView_d"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="d" />

                <TextView
                Android:id="@+id/headerTextView_e"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="e" />

                <TextView
                Android:id="@+id/headerTextView_f"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="f" />

                <TextView
                Android:id="@+id/headerTextView_g"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="g" />

                <TextView
                Android:id="@+id/headerTextView_h"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="h" />

                <TextView
                Android:id="@+id/headerTextView_i"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="i" />

                <TextView
                Android:id="@+id/headerTextView_j"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="j" />

                <TextView
                Android:id="@+id/headerTextView_k"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:text="k" />

            </LinearLayout>

            <androidx.core.widget.NestedScrollView
                Android:id="@+id/layout_bottom_sheet_scrollable_view"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:background="#FF00FF00"
                Android:fillViewport="true" >

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

                    <TextView
                        Android:id="@+id/textView0"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="0" />

                    <TextView
                        Android:id="@+id/textView1"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="1" />

                    <TextView
                        Android:id="@+id/textView2"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="2" />

                    <TextView
                        Android:id="@+id/textView3"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="3" />

                    <TextView
                        Android:id="@+id/textView4"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="4" />

                    <TextView
                        Android:id="@+id/textView5"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="5" />

                    <TextView
                        Android:id="@+id/textView6"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="6" />

                    <TextView
                        Android:id="@+id/textView7"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="7" />

                    <TextView
                        Android:id="@+id/textView8"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="8" />

                    <TextView
                        Android:id="@+id/textView9"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="9" />

                    <TextView
                        Android:id="@+id/textView10"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="10" />

                    <TextView
                        Android:id="@+id/textView11"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="11" />

                    <TextView
                        Android:id="@+id/textView12"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="12" />

                    <TextView
                        Android:id="@+id/textView13"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="13" />

                    <TextView
                        Android:id="@+id/textView14"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="14" />

                    <TextView
                        Android:id="@+id/textView15"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="15" />

                    <TextView
                        Android:id="@+id/textView16"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="16" />

                    <TextView
                        Android:id="@+id/textView17"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="17" />

                    <TextView
                        Android:id="@+id/textView18"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="18" />

                    <TextView
                        Android:id="@+id/textView19"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="19" />

                    <TextView
                        Android:id="@+id/textView20"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="20" />

                    <TextView
                        Android:id="@+id/textView21"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="21" />

                    <TextView
                        Android:id="@+id/textView22"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="22" />

                    <TextView
                        Android:id="@+id/textView23"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="23" />

                    <TextView
                        Android:id="@+id/textView24"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="24" />

                    <TextView
                        Android:id="@+id/textView25"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="25" />

                    <TextView
                        Android:id="@+id/textView26"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="26" />

                    <TextView
                        Android:id="@+id/textView27"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="27" />

                    <TextView
                        Android:id="@+id/textView28"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="28" />

                    <TextView
                        Android:id="@+id/textView29"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="29" />

                    <TextView
                        Android:id="@+id/textView30"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="30" />

                    <TextView
                        Android:id="@+id/textView31"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="31" />

                    <TextView
                        Android:id="@+id/textView32"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="32" />

                    <TextView
                        Android:id="@+id/textView33"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="33" />

                    <TextView
                        Android:id="@+id/textView34"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="34" />

                    <TextView
                        Android:id="@+id/textView35"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="35" />

                    <TextView
                        Android:id="@+id/textView36"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="36" />

                    <TextView
                        Android:id="@+id/textView37"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="37" />

                    <TextView
                        Android:id="@+id/textView38"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="38" />

                    <TextView
                        Android:id="@+id/textView39"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="39" />

                    <TextView
                        Android:id="@+id/textView40"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="40" />

                    <TextView
                        Android:id="@+id/textView41"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="41" />

                    <TextView
                        Android:id="@+id/textView42"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="42" />

                    <TextView
                        Android:id="@+id/textView43"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="43" />

                    <TextView
                        Android:id="@+id/textView44"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="44" />

                    <TextView
                        Android:id="@+id/textView45"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="45" />

                    <TextView
                        Android:id="@+id/textView46"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="46" />

                    <TextView
                        Android:id="@+id/textView47"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="47" />

                    <TextView
                        Android:id="@+id/textView48"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="48" />

                    <TextView
                        Android:id="@+id/textView49"
                        Android:layout_width="wrap_content"
                        Android:layout_height="wrap_content"
                        Android:text="49" />

                </LinearLayout>

            </androidx.core.widget.NestedScrollView>
        </LinearLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.Java

package com.example.bottomsheetwithscrollablecontent;

import Android.os.Bundle;
import Android.view.View;
import Android.widget.Button;

import com.google.Android.material.bottomsheet.BottomSheetBehavior;

import androidx.appcompat.app.AppCompatActivity;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

public class MainActivity extends AppCompatActivity {
    private CoordinatorLayout layout_coordinator;
    private View layout_coordinator_child;
    private View layout_bottom_sheet_header;

    private BottomSheetBehavior behavior;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        layout_coordinator = findViewById(R.id.layout_coordinator);
        layout_coordinator_child = layout_coordinator.findViewById(R.id.layout_coordinator_child);
        layout_bottom_sheet_header = layout_coordinator.findViewById(R.id.layout_bottom_sheet_header);

        behavior = BottomSheetBehavior.from(layout_coordinator_child);

        Button buttonPeek = findViewById(R.id.buttonPeek);
        buttonPeek.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                behavior.setPeekHeight(layout_bottom_sheet_header.getHeight());
                behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
            }
        });

        Button buttonExpand = findViewById(R.id.buttonExpand);
        buttonExpand.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        });

        Button buttonClose = findViewById(R.id.buttonClose);
        buttonClose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                behavior.setState(BottomSheetBehavior.STATE_HIDDEN);
            }
        });
    }
}

app/build.gradle

apply plugin: 'com.Android.application'

Android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.bottomsheetwithscrollablecontent"
        minSdkVersion 24
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-Android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0-beta01'
    implementation "com.google.Android.material:material:1.1.0-alpha04"
}
0
Michael Osofsky