Setzen Sie den Status von BottomSheetDialogFragment auf Erweitert

Lesezeit: 7 Minuten

Wie legen Sie den Status einer Fragmenterweiterung fest? BottomSheetDialogFragment zu erweitern mit BottomSheetBehavior#setState(STATE_EXPANDED) Verwenden der Android Support Design Library (v23.2.1)?

https://code.google.com/p/android/issues/detail?id=202396 sagt:

Die unteren Blätter werden zunächst auf STATE_COLLAPSED gesetzt. Rufen Sie BottomSheetBehavior#setState(STATE_EXPANDED) auf, wenn Sie es erweitern möchten. Beachten Sie, dass Sie die Methode nicht vor Ansichtslayouts aufrufen können.

Der empfohlene Praxis erfordert, dass zuerst eine Ansicht aufgeblasen wird, aber ich bin mir nicht sicher, wie ich das BottomSheetBehaviour auf ein Fragment (BottomSheetDialogFragment).

View bottomSheet = coordinatorLayout.findViewById(R.id.bottom_sheet);  
BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);  

Setzen Sie den Status von BottomSheetDialogFragment auf Erweitert
frau

“Beachten Sie, dass Sie die Methode nicht vor Ansichtslayouts aufrufen können.”

Der obige Text ist der Hinweis.

Dialoge haben einen Listener, der ausgelöst wird, sobald der Dialog gezeigt. Der Dialog kann nicht angezeigt werden, wenn er nicht angelegt ist.

Also, im onCreateDialog() Ihres modalen unteren Blattes (BottomSheetFragment), kurz bevor Sie den Dialog zurückgeben (oder irgendwo, wenn Sie einen Verweis auf den Dialog haben), rufen Sie auf:

// This listener's onShow is fired when the dialog is shown
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
    @Override
    public void onShow(DialogInterface dialog) {

        // In a previous life I used this method to get handles to the positive and negative buttons
        // of a dialog in order to change their Typeface. Good ol' days.

        BottomSheetDialog d = (BottomSheetDialog) dialog;
        
        // This is gotten directly from the source of BottomSheetDialog
        // in the wrapInBottomSheet() method
        FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);

        // Right here!
        BottomSheetBehavior.from(bottomSheet)
            .setState(BottomSheetBehavior.STATE_EXPANDED);
    }
});

In meinem Fall meine Gewohnheit BottomSheet stellte sich heraus:

@SuppressWarnings("ConstantConditions")
public class ShareBottomSheetFragment extends AppCompatDialogFragment {

    @NonNull @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        BottomSheetDialog dialog =
                new BottomSheetDialog(getActivity(), R.style.Haute_Dialog_ShareImage);

        dialog.setContentView(R.layout.dialog_share_image);

        dialog.findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });

        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                BottomSheetDialog d = (BottomSheetDialog) dialog;

                FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
                BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        });

        SwitchCompat switchview = (SwitchCompat) dialog.findViewById(R.id.switchview);
        switchview.setTypeface(FontCache.get(dialog.getContext(), lookup(muli, NORMAL)));

        return dialog;
    }
}

Lassen Sie mich wissen, ob das hilft.

AKTUALISIEREN

Beachten Sie, dass Sie auch überschreiben können BottomSheetDialogFragment wie:

public class SimpleInitiallyExpandedBottomSheetFragment extends BottomSheetDialogFragment {

    @NonNull @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);

        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                BottomSheetDialog d = (BottomSheetDialog) dialog;

                FrameLayout bottomSheet = (FrameLayout) d.findViewById(android.support.design.R.id.design_bottom_sheet);
                BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        });

        // Do something with your dialog like setContentView() or whatever
        return dialog;
    }
}

Aber ich verstehe wirklich nicht, warum das jemand als Basis tun möchte BottomSheetFragment macht nichts anderes als zurück zu a BottomSheetDialog.

AKTUALISIERUNG FÜR ANDROIDX

Bei Verwendung von AndroidX ist die zuvor gefundene Ressource unter android.support.design.R.id.design_bottom_sheet ist jetzt zu finden unter com.google.android.material.R.id.design_bottom_sheet.

  • Danke, ich habe diese Methode ausprobiert. Es macht die BottomSheetDialogFragment erscheinen ruckelig (scheint Frames in der Eröffnungsanimation zu überspringen), wenn es vom minimierten zum erweiterten Verhalten geht. Bearbeiten: Getestet auf Android Marshmallow- und KitKat-Geräten

    – Benutzer2560886

    25. März ’16 um 23:54


  • Bei mir funktioniert es perfekt. Kein Überspringen. Machen Sie noch etwas anderes, als nur einen Dialog zurückzugeben? Ich würde mich freuen, wenn Sie Ihren Beitrag mit Ihrem Code aktualisieren, damit ich eine bessere Idee habe.

    – frau

    26. März ’16 bei 0:37


  • Bekomme nur ich das Paket nicht finden können? android.support.design.R nach der Aktualisierung der Support-Bibliotheken?

    – natario

    17. September ’17 um 12:53 Uhr

  • Ich habe auch Probleme mit der Lösung android.support.design.R, genau wie @natario . Ich benutze implementation "com.google.android.material:material:1.0.0". Ich verwende auch AndroidX im Projekt.

    – hsson

    8. Oktober ’18 um 9:08


  • Bei Verwendung von AndroidX finden Sie die Ressource unter com.google.android.material.R.id.design_bottom_sheet

    – dringendx

    23. November ’18 um 0:35

Die Antwort von efeturi ist jedoch großartig, wenn Sie verwenden möchten onCreateView() um Ihr BottomSheet zu erstellen, anstatt mit zu gehen onCreateDialog(), hier ist der Code, den Sie unter Ihrem hinzufügen müssen onCreateView() Methode:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialog) {
            BottomSheetDialog d = (BottomSheetDialog) dialog;
            View bottomSheetInternal = d.findViewById(android.support.design.R.id.design_bottom_sheet);
            BottomSheetBehavior.from(bottomSheetInternal).setState(BottomSheetBehavior.STATE_EXPANDED);
        }
    });
    return inflater.inflate(R.layout.your_bottomsheet_content_layout, container, false);
}

  • Alternativ müssen Sie getDialog überhaupt nicht aufrufen. Ich finde, der sauberste Weg, dies zu tun, besteht darin, sowohl onCreateView als auch onCreateDialog zu überschreiben. Erstellen Sie Ihre Ansicht in onCreateView (wie bei jedem Fragment) und führen Sie den dialogspezifischen Code in onCreateDialog aus (rufen Sie super.onCreateDialog auf, um die Instanz abzurufen).

    – Stimsoni

    24. Mai ’16 um 3:47

  • Das rettet meinen Tag. Danke.

    – AndroidRuntimeException

    30. März ’17 um 14:33

  • @Stimsoni onCreateView wird nicht aufgerufen, wenn onCreateDialog verwendet wird. developer.android.com/reference/android/support/v4/app/…

    – Vincent Paing

    11. März ’19 um 5:35


  • @Vincent_Paing, Ja, das ist es. In Ihrem angehängten Link steht “onCreateView muss nicht implementiert werden”. Es heißt nicht, dass es nicht aufgerufen wird. Sehen Sie sich hier den Quellcode an github.com/material-components/material-components-android/blob/…. Die Standardimplementierung ruft onCreateDialog auf, um das untere Blatt zu erstellen, und jede obige Lösung verwendet weiterhin onCreateView, was bedeutet, dass beide immer aufgerufen werden. Stellen Sie nur sicher, dass Sie immer noch super.onCreateDialog() aufrufen, wenn Sie es überschreiben.

    – Stimsoni

    12. März ’19 um 5:13

  • in BottomSheetDialogFragment stürzt es mich in onCreateView() ab Ich habe es in onViewCreated() eingefügt und es ist perfekt! Danke schön

    – visper

    7. September ’20 um 10:23


Setzen Sie den Status von BottomSheetDialogFragment auf Erweitert
DYS

Eine einfache und elegante Lösung:

BottomSheetDialogFragment könnte untergeordnet werden, um dies zu beheben:

class NonCollapsableBottomSheetDialogFragment extends BottomSheetDialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);

        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                FrameLayout bottomSheet = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);

                BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
                behavior.setSkipCollapsed(true);
                behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
            }
        });
        return dialog;
    }
}

Also erweitere diese Klasse statt BottomSheetDialogFragment um Ihr eigenes unteres Blatt zu erstellen.

Notiz

Veränderung com.google.android.material.R.id.design_bottom_sheet zu android.support.design.R.id.design_bottom_sheet wenn Ihr Projekt alte Android-Supportbibliotheken verwendet.

  • Scheint zu sein com.google.android.material.R jetzt statt android.support.design.R.

    – EpicPandaForce

    26. August ’19 um 14:19

  • @EpicPandaForce Klar. Das Android-Team von Google hat kürzlich die ehemalige Support-Bibliothek neu gepackt.

    – DYS

    27. August ’19 bei 4:28

Setzen Sie den Status von BottomSheetDialogFragment auf Erweitert
Tina Lu

Ich denke, die oben genannten sind besser. Leider habe ich diese Lösung nicht gefunden, bevor ich gelöst hatte. Aber schreibe meine Lösung. allen ziemlich ähnlich.

================================================ ================================

Ich stehe vor dem gleichen Problem. Das habe ich gelöst. Das Verhalten ist in BottomSheetDialog ausgeblendet, das zum Abrufen des Verhaltens verfügbar ist. Wenn Sie Ihr übergeordnetes Layout nicht in CooridateLayout ändern möchten, können Sie dies versuchen.

SCHRITT 1: Anpassen des BottomSheetDialogFragment

open class CBottomSheetDialogFragment : BottomSheetDialogFragment() {
   //wanna get the bottomSheetDialog
   protected lateinit var dialog : BottomSheetDialog 
   override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
      dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
      return dialog
   }

   //set the behavior here
   fun setFullScreen(){
      dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
   }
}

SCHRITT 2: Lassen Sie Ihr Fragment dieses benutzerdefinierte Fragment erweitern

class YourBottomSheetFragment : CBottomSheetDialogFragment(){
    
   //make sure invoke this method after view is built
   //such as after OnActivityCreated(savedInstanceState: Bundle?)
   override fun onStart() {
      super.onStart()
      setFullScreen()//initiated at onActivityCreated(), onStart()
   }
}

Meine Antwort ist mehr oder weniger die gleiche wie die meisten der obigen Antworten, mit einer leichten Modifikation. Anstatt findViewById zu verwenden, um zuerst die untere Blattansicht zu finden, habe ich es vorgezogen, keine Ressourcen-IDs für die Framework-Ansicht fest zu codieren, da sie sich in Zukunft ändern könnten.

setOnShowListener(dialog -> {
            BottomSheetBehavior bottomSheetBehavior = ((BottomSheetDialog)dialog).getBehavior();
            bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
        });

1641936975 414 Setzen Sie den Status von BottomSheetDialogFragment auf Erweitert
leigo

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return super.onCreateDialog(savedInstanceState).apply {
        setOnShowListener {
            ([email protected] as BottomSheetDialog).behavior.setState(
                BottomSheetBehavior.STATE_EXPANDED
            )
        }
    }
}

1641936975 842 Setzen Sie den Status von BottomSheetDialogFragment auf Erweitert
Yeldar.N

BottomSheetDialogFragment:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    (dialog as? BottomSheetDialog)?.behavior?.state = STATE_EXPANDED
}

oder wenn Sie bereit sind zu zeigen:

private fun onContentLoaded(items: List<Any>) {
    adapter.submitList(items)
    (dialog as? BottomSheetDialog)?.behavior?.state = STATE_EXPANDED
}

.

390600cookie-checkSetzen Sie den Status von BottomSheetDialogFragment auf Erweitert

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy