it-swarm.com.de

Höhe von BottomSheetBehavior dynamisch ändern

Ich verwende die BottomSheetBehavior von Google, die kürzlich von AppCompat v23.2 veröffentlicht wurde. Die Höhe meines untersten Blattes hängt von dem Inhalt ab, der im unteren Blatt angezeigt wird (ähnlich wie Google es in seiner Maps-App selbst tut).

Es funktioniert problemlos mit den ursprünglich geladenen Daten, aber meine Anwendung ändert den angezeigten Inhalt während der Laufzeit. Wenn dies geschieht, behält das unterste Blatt seine alte Höhe bei, was entweder zu ungenutzten Speicherplatz am unteren Rand oder zu einem Ausschnitt führt.

Gibt es eine Möglichkeit, das untere Blattlayout anzuweisen, die für den erweiterten Status verwendete Höhe neu zu berechnen (wenn die Höhe der Variable ViewGroup auf MATCH_HEIGHT gesetzt ist) oder die erforderliche Höhe manuell festzulegen?


EDIT: Ich habe auch versucht, invalidate() für die ViewGroup und das übergeordnete Element manuell aufzurufen, jedoch ohne Erfolg.

31
miho

Ich hatte das gleiche Problem mit RelativeLayout wie mein unteres Blatt. Die Höhe wird nicht neu berechnet. Ich musste die Höhe durch den neuen neu berechneten Wert einstellen und BottomSheetBehavior.onLayoutChild aufrufen.

Dies ist meine temporäre Lösung:

coordinatorLayout = (CoordinatorLayout)findViewById(R.id.coordinator_layout);
bottomSheet = findViewById(R.id.bottom_sheet);

int accountHeight = accountTextView.getHeight();
accountTextView.setVisibility(View.GONE);

bottomSheet.getLayoutParams().height = bottomSheet.getHeight() - accountHeight;
bottomSheet.requestLayout();
behavior.onLayoutChild(coordinatorLayout, bottomSheet, ViewCompat.LAYOUT_DIRECTION_LTR);
28
Phyrum Tea

Sie können BottomSheetBehavior#setPeekHeight dafür verwenden.

FrameLayout bottomSheet = (FrameLayout) findViewById(R.id.bottom_sheet);
BottomSheetBehavior<FrameLayout> behavior = BottomSheetBehavior.from(bottomSheet);
behavior.setPeekHeight(newHeight);

Dadurch wird das unterste Blatt nicht automatisch auf die Peek-Höhe verschoben. Sie können BottomSheetBehavior#setState aufrufen, um Ihr unteres Blatt an die neue Peek-Höhe anzupassen.

behavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
8
Yuichi Araki

Obwohl das Problem in der Supportbibliothek> = 24.0.0 behoben wurde, müssen Sie die ältere Version aus irgendeinem Grund verwenden. 

mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull final View bottomSheet, int newState) {
            bottomSheet.post(new Runnable() {
                @Override
                public void run() {
                    //workaround for the bottomsheet  bug
                    bottomSheet.requestLayout();
                    bottomSheet.invalidate();
                }
            });
        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        }
    });
1
Ankush Chugh

Ich war mit dem gleichen Problem konfrontiert. Beim Versuch, die Peek-Höhe basierend auf ihrem Inhalt zu aktualisieren, wurde die Höhe eines vorherigen Layouts ermittelt. Dies ist sinnvoll, da das neue Layout noch nicht stattgefunden hat. Durch das Posten im UI-Thread wird die Layouthöhe nach dem neuen Layout berechnet, und es wird eine weitere Layoutanforderung zur Aktualisierung des unteren Blattes auf die richtige Höhe erstellt.

void show() {
    setVisibility(View.VISIBLE);
    post(new Runnable() {
        @Override
        public void run() {
            mBottomSheetBehavior.setPeekHeight(findViewById(R.id.sheetPeek).getHeight());
            requestLayout();
        }
    })
}
0
Harald Unander

Ich war mit demselben Problem konfrontiert, als ich eine Recyclingübersicht in einem BottomSheet verwendete und die Elemente dynamisch geändert wurden. Wie @sosite in seinem Kommentar erwähnt hat, wird das Problem protokolliert und in der neuesten Version behoben. . Problemprotokoll hier

Aktualisieren Sie einfach Ihre Design-Support-Bibliothek auf Version 24.0.0 und überprüfen Sie sie.

0
hari_shankar

Ich habe @ HaraldUnander Rat befolgt und es gab mir eine Idee, die tatsächlich funktioniert hat. Wenn Sie einen Thread ausführen (mit der post-Methode könnte dies nicht funktionieren), nachdem BottomSheetBehavior.state Programmgesteuert auf STATE_COLLAPSED Eingestellt wurde, können Sie bereits die Höhe Ihrer Aufrufe und erhalten Setze das peekHeight abhängig vom Inhalt.

Also setzen Sie zuerst den BottomSheetBehavior:

BottomSheetBehavior.from(routeCaptionBottomSheet).state = BottomSheetBehavior.STATE_COLLAPSED

Und dann stellst du die Höhe dynamisch ein:

thread {
    activity?.runOnUiThread {
        val dynamicHeight = yourContainerView.height
        BottomSheetBehavior.from(bottomSheetView).peekHeight = dynamicHeight
    }
}

Wenn Sie Java (Ich verwende Kotlin mit Anko für Threads)) verwenden, könnte dies Folgendes bewirken:

new Thread(new Runnable() {
    public void run() {
        val dynamicHeight = yourContainerView.height
        BottomSheetBehavior.from(bottomSheetView).peekHeight = dynamicHeight
    }
}).start();
0
xarlymg89