web-dev-qa-db-fra.com

Comment imiter le comportement en trois phases de la feuille de fond de Google Maps?

Contexte

Je suis chargé de créer une interface utilisateur similaire à la façon dont Google Maps affiche une feuille de fond pour un résultat trouvé.

Il comporte trois phases différentes:

  1. Contenu du bas. La partie supérieure est toujours touchable et ne fait rien défiler en bas
  2. Contenu en plein écran, tandis que la zone supérieure a un en-tête volumineux.
  3. Contenu en plein écran, tandis que la zone supérieure contient uniquement la barre d’outils.

Voici ce dont je parle sur Google Maps:

Enter image description here

Le problème

Le problème est que la feuille de fond ne fait pas encore partie de la bibliothèque de conception (bien que cela ait été demandé, ici ).

Non seulement cela, mais l'interface utilisateur semble assez complexe et nécessite une gestion de la barre d'outils sur plusieurs phases.

Ce que j'ai essayé

J'ai trouvé une bonne (assez) bibliothèque pour la feuille du bas ( ici ), et ajouté du contenu à son fragment, d'avoir à peu près les mêmes vues que celles indiquées sur les exemples de conception de matériau (comme ici ), afin de disposer d'un CollapsingToolbarLayout à prendre en charge des phases 2 + 3.

Dans l'application que je crée, je dois également déplacer une icône lorsque vous faites défiler l'écran, mais je pense que si je réussis avec le reste, cela devrait être facile. Voici le 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);
            }
        });
    }
}

Ca marche presque bien. Le seul problème est le passage du n ° 3 au n ° 2:

enter image description here

La question

Quel est le problème avec le code? Que puis-je faire pour obtenir le comportement requis?

105
android developer

Note : Lire les modifications au bas


OK, j’ai trouvé un moyen de le faire, mais j’ai dû changer le code de plusieurs classes, pour que la feuille du bas sache l’état de appBarLayout (développé ou non) et ignore le défilement au cas où c’est le cas. non élargi:

BottomSheetLayout.Java

Champs ajoutés:

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

init () - a ajouté ceci:

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

Ajout de la fonction pour définir le appBarLayout:

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

onDetachedFromWindow () - ajouté ceci:

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

onTouchEvent () - ajouté ceci:

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

Ce sont les principaux changements. Maintenant pour ce qui les définit:

MyFragment.Java

onCreateView () - ajouté ceci:

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

J'ai aussi ajouté cette fonction:

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

Voici comment l'activité indique au fragment l'appBarLayout:

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

Le projet est maintenant disponible sur GitHub:

https://github.com/AndroidDeveloperLB/ThreePhasesBottomSheet

J'espère qu'il n'y a pas de bugs.


La solution a des bogues, malheureusement, donc je ne marquerai pas cette réponse comme étant la bonne:

  1. Cela ne fonctionne bien que sur Android 6 et plus. Les autres ont le comportement étrange de montrer la page du bas étendue pendant une toute petite fraction du temps, à chaque fois.
  2. Les changements d'orientation n'enregistrent pas du tout l'état du défilement, je l'ai donc désactivé.
  3. Problème rare de pouvoir faire défiler le contenu de la feuille du bas pendant qu'elle est encore réduite (en bas)
  4. Si un clavier était affiché auparavant, la page du bas peut devenir plein écran lorsque vous essayez de regarder.

Si quelqu'un peut t'aider, fais-le.


Pour le problème n ° 1, j'ai essayé d'ajouter un correctif en définissant la visibilité sur INVISIBLE lorsque la feuille du bas n'est pas encore vue, mais cela ne fonctionne pas toujours, surtout si un clavier est affiché.


Pour le problème n ° 1, j'ai trouvé comment résoudre ce problème en enveloppant simplement (dans "fragment_my.xml") le CoordinatorLayout avec la vue que vous souhaitez utiliser (j'ai utilisé FrameLayout) et en insérant également une vue en taille réelle. il (je viens de mettre "View"), en tant que tel:

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

Il a probablement confondu la feuille de fond lorsque j'ai eu l’avis de CoordinatorLayout. J'ai mis à jour le projet, mais s'il y a un moyen d'avoir une solution plus agréable, j'aimerais le savoir.


Ces derniers mois, Google a publié sa propre classe bottomSheet, mais comme j'ai constaté qu'elle posait de nombreux problèmes, je ne peux même pas l'essayer.

18
android developer

BIG UPDATE

Parce qu'il y avait 4 ou 5 questions sur le même sujet, MAIS avec différentes exigences, et j'ai essayé de répondre à toutes, mais un administrateur impoli les a supprimées/fermées, ce qui m'a obligé à créer un ticket pour chacune d'elles et à les remplacer par Pour éviter le "copier/coller", je vous laisserai un lien vers le réponse complète où vous pourrez trouver toutes les explications sur la façon d'obtenir un comportement complet tel que Google Maps.


Répondre à votre question

Comment imiter le comportement en trois phases de la feuille de fond de Google Maps?

Avec la bibliothèque de support 23.x.x +, vous pouvez le faire en modifiant le BottomSheetBehavior par défaut, en ajoutant un autre stat avec les étapes suivantes:

  1. Créez une classe Java et étendez-la à partir de CoordinatorLayout.Behavior<V>
  2. Copiez le code de collage du fichier par défaut BottomSheetBehavior dans votre nouveau fichier.
  3. Modifiez la méthode clampViewPositionVertical avec le code suivant:

    @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. Ajouter un nouvel état:

    public static final int STATE_ANCHOR_POINT = X;
    
  5. Modifiez les méthodes suivantes: onLayoutChild, onStopNestedScroll, BottomSheetBehavior<V> from(V view) et setState (facultatif)

Je vais ajouter ces méthodes modifiées et un lien vers l'exemple de projet .

Et voici à quoi ça ressemble:
CustomBottomSheetBehavior

15
MiguelHincapieC

Avez-vous essayé cela? http://Android-developers.blogspot.in/2016/02/Android-support-library-232.html?m=1 Ici, il est indiqué que nous pouvons simplement spécifier un comportement de présentation de feuille de fond.

UPDATE:

Fondamentalement, le lien

En attachant un BottomSheetBehavior à une vue enfant d'un CoordinatorLayout (c'est-à-dire en ajoutant app: layout_behavior = "Android.support.design.widget.BottomSheetBehavior"), vous obtiendrez automatiquement la détection de contact appropriée pour la transition entre cinq états:

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

Si vous souhaitez recevoir des rappels de changements d’état, vous pouvez ajouter un 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  
   }  
 });  

Bien que BottomSheetBehavior capture le cas de la feuille de fond persistante, cette version fournit également un BottomSheetDialog et un BottomSheetDialogFragment pour remplir le cas d'utilisation des feuilles de fond modales. Remplacez simplement AppCompatDialog ou AppCompatDialogFragment par leurs équivalents de la dernière page pour que votre boîte de dialogue soit stylée comme une dernière page.

0
Vaibhav Sharma

J'ai également dû implémenter une vue similaire à la façon dont Google Maps affiche une feuille de fond pour un résultat trouvé.

Voici à quoi ressemble le mien:

Peek view

Expand view scrolled to top

Expand view scrolled to bottom

Au début, j'ai défini une feuille de fond avec un en-tête et un contenu défilable, mais layout_height ne semblait pas envelopper le contenu, ni l'en-tête ni le contenu défilable, malgré la spécification de wrap_content.

Ce problème a disparu lorsque j'ai utilisé LinearLayout au lieu de ConstraintLayout pour la présentation enfant de CoordinatorLayout (et pour ses enfants).

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