it-swarm.com.de

Wie kann man das 3-Phasen-Verhalten von Google Maps im unteren Blatt nachahmen?

Hintergrund

Ich habe die Aufgabe, eine Benutzeroberfläche zu erstellen, die sich so verhält, wie Google Maps ein unteres Blatt für ein gefundenes Ergebnis anzeigt.

Es gibt drei verschiedene Phasen:

  1. Inhalt unten. Der obere Bereich ist immer noch berührbar und führt am unteren Rand keinen Bildlauf durch
  2. Vollbildinhalt, während der obere Bereich eine große Kopfzeile hat.
  3. Vollbildinhalt, während der obere Bereich nur die Symbolleiste enthält.

Worüber ich in Google Maps spreche:

Enter image description here

Das Problem

Das untere Blatt ist noch nicht Teil der Designbibliothek (obwohl es angefordert wurde, hier ).

Darüber hinaus erscheint die Benutzeroberfläche recht komplex und erfordert die Verwaltung der Symbolleiste in mehreren Phasen.

Was ich versucht habe

Ich habe eine gute (genug) Bibliothek für das unterste Blatt ( hier ) gefunden und dem Fragment-Sample Inhalt hinzugefügt, um über das zu verfügen Dieselben Ansichten wie in den Materialdesign-Beispielen (wie hier ), um ein CollapsingToolbarLayout zu erhalten, das die Phasen 2 + 3 berücksichtigt.

In der App, die ich mache, muss ich auch ein Symbol bewegen, während Sie scrollen, aber ich denke, dass dies einfach sein sollte, wenn ich mit dem Rest Erfolg habe. Hier ist der Code:

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);
            }
        });
    }
}

Es funktioniert fast gut. Das einzige Problem ist der Übergang von # 3 zurück zu # 2:

enter image description here

Die Frage

Was ist los mit dem Code? Was kann ich tun, um das gewünschte Verhalten zu erreichen?

105

Hinweis : Lesen Sie die Änderungen unten


OK, ich habe eine Möglichkeit gefunden, aber ich musste den Code mehrerer Klassen ändern, damit das untere Blatt den Status des appBarLayout kennt (erweitert oder nicht) und den Bildlauf nach oben ignoriert, falls dies der Fall ist nicht erweitert:

BottomSheetLayout.Java

Felder hinzugefügt:

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

init () - hat Folgendes hinzugefügt:

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

Funktion zum Setzen des appBarLayout hinzugefügt:

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

onDetachedFromWindow () - hat Folgendes hinzugefügt:

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

onTouchEvent () - hat Folgendes hinzugefügt:

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

Das waren die Hauptänderungen. Nun zu dem, was sie ausmacht:

MyFragment.Java

onCreateView () - hat Folgendes hinzugefügt:

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

Ich habe auch diese Funktion hinzugefügt:

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

So teilt die Aktivität dem Fragment das appBarLayout mit:

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

Das Projekt ist jetzt auf GitHub verfügbar:

https://github.com/AndroidDeveloperLB/ThreePhasesBottomSheet

Ich hoffe es hat keine Bugs.


Die Lösung hat leider Fehler, daher werde ich diese Antwort nicht als die richtige markieren:

  1. Es funktioniert nur gut auf Android 6 und höher. Andere haben das seltsame Verhalten, dass das untere Blatt jedes Mal, wenn es angezeigt wird, für einen winzigen Bruchteil einer Zeit erweitert wird.
  2. Änderungen an der Ausrichtung speichern den Status des Bildlaufs überhaupt nicht, daher habe ich ihn deaktiviert.
  3. Seltenes Problem, dass der Inhalt des untersten Blattes gescrollt werden kann, während es noch reduziert ist (unten)
  4. Wenn zuvor eine Tastatur angezeigt wurde, wird das unterste Blatt möglicherweise als Vollbild angezeigt, wenn versucht wird, einen Blick darauf zu werfen.

Wenn jemand dabei helfen kann, bitte.


Bei Problem Nr. 1 habe ich versucht, einen Fix hinzuzufügen, indem die Sichtbarkeit auf UNSICHTBAR gesetzt wurde, wenn das untere Blatt noch nicht eingesehen wurde, dies funktioniert jedoch nicht immer, insbesondere, wenn eine Tastatur angezeigt wird.


Bei Problem Nr. 1 habe ich herausgefunden, wie es behoben werden kann, indem ich das CoordinatorLayout einfach in "fragment_my.xml" mit einer beliebigen Ansicht umgepackt habe (ich habe FrameLayout verwendet) und auch eine Ansicht in voller Größe eingefügt es (ich habe nur "View" gesetzt), als solches:

<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 
    ...

Wahrscheinlich hat es das bottomSheet verwirrt, als ich das CoordinatorLayout als Ansicht hatte. Ich habe das Projekt aktualisiert, aber wenn es eine bessere Lösung gibt, würde ich gerne davon erfahren.


In den letzten Monaten hat Google eine eigene bottomSheet-Klasse veröffentlicht, aber wie ich festgestellt habe, gibt es viele Probleme, sodass ich sie nicht einmal ausprobieren kann.

18

GROSSES UPDATE

Weil es ungefähr 4 oder 5 Fragen zum selben Thema gab, ABER mit VERSCHIEDENEN Anforderungen, und ich versuchte, alle zu beantworten, aber ein unhöflicher Administrator löschte/schloss sie, sodass ich für jede ein Ticket erstellte und sie in änderte Vermeiden Sie "Kopieren Einfügen". Ich werde Ihnen einen Link zu Vollständige Antwort geben, in dem Sie alle Erklärungen finden, wie Sie ein vollständiges Verhalten wie bei Google Maps erzielen können.


Beantwortung Ihrer Frage

Wie kann man das 3-Phasen-Verhalten von Google Maps im unteren Blatt nachahmen?

Mit der Unterstützungsbibliothek 23.x.x + können Sie den Standardwert BottomSheetBehavior ändern und eine weitere Statistik mit den folgenden Schritten hinzufügen:

  1. Erstelle eine Java Klasse und erweitere sie von CoordinatorLayout.Behavior<V>
  2. Kopieren Sie den Einfügecode aus der Standarddatei BottomSheetBehavior in die neue Datei.
  3. Ändern Sie die Methode clampViewPositionVertical mit dem folgenden Code:

    @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. Neuen Staat hinzufügen:

    public static final int STATE_ANCHOR_POINT = X;
    
  5. Ändern Sie die nächsten Methoden: onLayoutChild, onStopNestedScroll, BottomSheetBehavior<V> from(V view) und setState (optional)

Ich werde diese geänderten Methoden hinzufügen und einen Link zum Beispielprojekt .

Und so sieht es aus:
CustomBottomSheetBehavior

15
MiguelHincapieC

Hast du das probiert? http://Android-developers.blogspot.in/2016/02/Android-support-library-232.html?m=1 Hier steht, dass wir nur ein Layoutverhalten für das untere Blatt festlegen können.

UPDATE:

Grundsätzlich heißt der Link:

Durch Anhängen eines BottomSheetBehavior an eine untergeordnete Ansicht eines CoordinatorLayout (d. H. Hinzufügen von app: layout_behavior = "Android.support.design.widget.BottomSheetBehavior") erhalten Sie automatisch die entsprechende Berührungserkennung für den Übergang zwischen fünf Zuständen:

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+).

Wenn Sie Rückrufe von Statusänderungen erhalten möchten, können Sie einen BottomSheetCallback hinzufügen:

// 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  
   }  
 });  

Während BottomSheetBehavior den beständigen unteren Blattfall erfasst, bietet diese Version auch BottomSheetDialog und BottomSheetDialogFragment, um den Anwendungsfall für modale untere Blätter auszufüllen. Ersetzen Sie einfach AppCompatDialog oder AppCompatDialogFragment durch die entsprechenden Unterblätter, um Ihr Dialogfeld als Unterblatt zu formatieren.

0
Vaibhav Sharma

Ich musste auch eine ähnliche Ansicht implementieren, wie Google Maps ein unteres Blatt für ein gefundenes Ergebnis anzeigt.

So sieht meins aus:

Peek view

Expand view scrolled to top

Expand view scrolled to bottom

Zuerst definierte ich ein unteres Blatt mit einer Kopfzeile und scrollbarem Inhalt, aber die layout_height schien trotz der Angabe von wrap_content Weder den Inhalt der Kopfzeile noch den scrollbaren Inhalt zu umbrechen.

Dieses Problem verschwand, als ich LinearLayout anstelle von ConstraintLayout für das untergeordnete Layout des CoordinatorLayout (und für die untergeordneten) verwendete.

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