Android So implementieren Sie Bottom Sheet aus Material Design-Dokumenten

79

Wie implementieren Sie die Bottom-Sheet-Spezifikation? http://www.google.com/design/spec/components/bottom-sheets.html

Das neue Update für Google Drive zeigt dies mit der Taste Floating Action Button ->

Geben Sie hier die Bildbeschreibung ein

Zugegeben, die Spezifikationen sagen niemals etwas über abgerundete Ecken aus, unabhängig davon, ob dies möglich ist, nur unsicher, wie es zu tun ist. Derzeit wird die AppCompat-Bibliothek verwendet und das Ziel auf 21 festgelegt.

Vielen Dank

John Shelley
quelle
Link ist unterbrochen. Neuer Link material.io/design/components/sheets-bottom.html#usage
Ray Li

Antworten:

66

Bearbeiten

Das BottomSheetist jetzt Teil des android-support-library. Siehe John Shelleys Antwort .


Leider gibt es derzeit keine "offizielle" Möglichkeit, dies zu tun (zumindest keine, die mir bekannt ist).
Glücklicherweise gibt es eine Bibliothek namens "BottomSheet" (Klick), die das Erscheinungsbild von BottomSheetund nachahmt und Android 2.1 und höher unterstützt.

Im Fall der Drive-App sieht der Code mit dieser Bibliothek folgendermaßen aus:

    new BottomSheet.Builder(this, R.style.BottomSheet_Dialog)
            .title("New")
            .grid() // <-- important part
            .sheet(R.menu.menu_bottom_sheet)
            .listener(new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            // TODO
        }
    }).show();

menu_bottom_sheet (im Grunde eine Standardressource /res/menu/*.xml)

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/folder"
        android:title="Folder"
        android:icon="@drawable/ic_action_folder" />
    <item
        android:id="@+id/upload"
        android:title="Upload"
        android:icon="@drawable/ic_action_file_upload" />
    <item
        android:id="@+id/scan"
        android:title="Scan"
        android:icon="@drawable/ic_action_camera_alt" />
</menu>

Die Ausgabe sieht folgendermaßen aus:

Bild des unteren Blattes

Was meiner Meinung nach dem Original ziemlich nahe kommt. Wenn Sie mit den Farben nicht zufrieden sind, können Sie sie anpassen - siehe hier (klicken) .

umkehren
quelle
Boom. Genau das suche ich! Ich werde es heute Abend versuchen!
John Shelley
1
Das ist großartig, danke fürs Teilen! Was ist, wenn Sie alle Optionen anzeigen möchten, die in einer Freigabeabsicht angezeigt werden? Sie werden dynamisch basierend auf den auf dem Gerät installierten Apps generiert. Irgendwelche Gedanken darüber, wie das erreicht werden kann?
Katze
1
@Cat Nun, im Grunde müssen Sie nur eine Liste aller Anwendungen abrufen , die die Absicht verarbeiten können (siehe diese StackO-Frage zum Beispiel) und sie dem Adapter hinzufügen, der das BottomSheet "füttert". Sie können auch das offizielle Beispiel der Bibliothek sehen, das genau das tut, was Sie anfordern. ( Klicken Sie auf - Zeile 153 - 179 ).
ReVerse
das hat funktioniert, danke @reVerse! Am Ende habe ich den Code in der getShareActionsMethode wiederverwendet , um alle möglichen Freigabeoptionen zu erhalten. Übrigens auch nützlich, um .limit(R.integer.num_share_actions)den Builder aufzurufen, es sei denn, Sie möchten, dass das Blatt den gesamten Bildschirm abdeckt
Cat
1
@ JohnShelley Das ist in Ordnung, absolut. Ich würde auch empfehlen, sich für die "offizielle Lösung" zu entscheiden, obwohl sie im Moment wirklich begrenzt ist, aber zumindest Google hat den Grundstein gelegt. ;)
reVerse
65

Beantworte meine eigene Frage, damit Entwickler wissen, dass die neue Support-Bibliothek dies endlich bietet! Alle begrüßen das mächtige Google!

Ein Beispiel aus dem Android-Entwicklerblog :

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

Die Antwort von @ reVerse oben ist immer noch eine gültige Option, aber es ist schön zu wissen, dass es einen Standard gibt, den auch Google unterstützt.

John Shelley
quelle
Danke fürs Schreiben. Ich denke, dies sollte jetzt die "richtige" Antwort sein :)
Vine'th
@androiddeveloper fertig. Angesichts der Tatsache, dass es sich jetzt um eine Support-spezifische Sache handelt, haben Benutzer meiner Meinung nach mehr Glück, wenn sie nach diesen Beispielen suchen. Als ich die Frage ursprünglich stellte, war sie nicht in der Support-Bibliothek enthalten. Wenn die Frage "So implementieren Sie die untere
John Shelley
@ JohnShelley Müssen Sie nicht auch XML-Inhalte verwenden? Ist es möglich, das Peek / Collapse des unteren Blattes (oder wie auch immer es heißt, wenn es sich unten befindet) so einzustellen, dass eine Wrap-Content-Ansicht angezeigt wird, und wenn es erweitert wird, als Vollbild angezeigt zu werden?
Android-Entwickler
4
Ich denke, es gibt viele Leute, die sich fragen, wie man die neue Support-API von Google verwendet, und Vipul Shah hat einen großartigen YouTube-Link, der Ihnen helfen kann, die Verwendung zu verstehen. Weitere Informationen finden
Minh Truong
Die Frage bleibt: Wie wird das Menü für das untere Blatt implementiert? Wo sind Menüpunkte im obigen Beispiel ??????? Sie wissen, die Menüpunkte, auf die Sie klicken ...
ekashking
8

Folgen Sie dem Blog-Beitrag: http://android-developers.blogspot.com/2016/02/android-support-library-232.html

Meine XML sah am Ende so aus:

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/coordinator_layout"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <LinearLayout
        android:id="@+id/bottom_sheet"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:orientation="horizontal"
        app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
        <ImageView
            android:src="@android:drawable/ic_input_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
</android.support.design.widget.CoordinatorLayout>

Und in meiner onCreateView meines Fragments:

    coordinatorLayout = (CoordinatorLayout)v.findViewById(R.id.coordinator_layout);
    View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);
    BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
    behavior.setPeekHeight(100);
    behavior.setBottomSheetCallback(new BottomSheetBehavior.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
        }
    });

Der Standardwert von setPeekHeight ist 0. Wenn Sie ihn also nicht festlegen, können Sie Ihre Ansicht nicht sehen.

mcorrado
quelle
Ja, die XML ist genau so, wie mein Fragment aussah. Funktioniert es nicht für dich?
mcorrado
Die Standard-Peek-Höhe ist -1 (AUTO!), Nicht 0.
Zordid
1
Wenn Sie AndroidX verwenden, beachten Sie die Änderung des Paketnamens:com.google.android.material.bottomsheet.BottomSheetBehavior
Ultimo_m
Wo sind die Menüpunkte ??????????????????? (der ganze Punkt des unteren
Blattmenüs
7

Sie können jetzt die offizielle BottomSheetBehaviorAPI aus der Android-Support-Bibliothek 23.2 verwenden.

Unten finden Sie ein Beispielcode-Snippet

bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottomSheet));

case R.id.expandBottomSheetButton:
 bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
 break;
case R.id.collapseBottomSheetButton:
 bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
 break;
case R.id.hideBottomSheetButton:
 bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
 break;
case R.id.showBottomSheetDialogButton:
 new MyBottomSheetDialogFragment().show(getSupportFragmentManager(), "sample");

Weitere Informationen finden Sie im YouTube-Tutorial zu Android BottomSheet .

Vipul
quelle
Hallo Vipul, danke für den Link. Ich habe jedoch eine Frage. Ist es möglich, einen Ankerpunkt für das untere Blatt festzulegen?
Marshmallowinvacuum
Super YouTube-Link. Haben Sie den Quellcode irgendwo in einem öffentlichen Repo?
John Shelley
Großartig
5

Ich würde mit geraden Ecken fahren, wie es in den Richtlinien steht. Für die Implementierung ist es vielleicht am besten, die Idee aus diesem Projekt zu verwenden: https://github.com/umano/AndroidSlidingUpPanel

Ich denke, Sie könnten es so verwenden, wie es ist, oder die Idee für die Implementierung übernehmen. Ein weiterer großartiger Artikel zur Implementierung eines ähnlichen Schiebetafels finden Sie hier: http://blog.neteril.org/blog/2013/10/10/framelayout-your-best-ui-friend/

Zh. Atanasov
quelle
5

Hier sind einige der anderen Optionen:

  • Es gibt eine von Flipboard , die Einbettungsaktivität muss jedoch geändert werden, damit das Bottomheet funktioniert.
  • Tutti- chs Bottomsheet : Dies wurde aus der ResolverActivity von Android Repo extrahiert und die Startaktivität muss nicht geändert werden.
Weinstock
quelle