Ich versuche, das Ziehen von Benutzern zu deaktivieren BottomSheet
. Der Grund, warum ich deaktivieren möchte, sind zwei Dinge. 1. Es verhindert, dass das ListView
Bild nach unten gescrollt wird. 2. Ich möchte nicht, dass Benutzer das Ziehen durch Ziehen schließen, sondern mit einer Schaltfläche auf dem BottomSheetView
. Das habe ich getan
bottomSheetBehavior = BottomSheetBehavior.from(bottomAnc);
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
//Log.e("BottomSheet", "Expanded");
} else if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
//Log.e("BottomSheet", "Collapsed");
}
}
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
// React to dragging events
bottomSheet.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
return false;
default:
return true;
}
}
});
}
});
Das bottomSheetLayout
<?xml version="1.0" encoding="utf-8"?><FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
app:behavior_hideable="true"
app:behavior_peekHeight="0dp"
app:layout_behavior="@string/bottom_sheet_behavior"
android:id="@+id/bottomSheet">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:elevation="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<TextView
android:id="@+id/text1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Order Items"
android:layout_margin="16dp"
android:textAppearance="@android:style/TextAppearance.Large"/>
<Button
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:background="@drawable/bg_accept"/>
<Button
android:layout_width="50dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:background="@drawable/bg_cancel"/>
</LinearLayout>
<ListView
android:id="@+id/item_edit"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:divider="@color/md_divider_black"
android:dividerHeight="1dp"/>
</LinearLayout>
</android.support.v7.widget.CardView>
android
android-support-library
android-support-design
Abubakar Oladeji
quelle
quelle
Antworten:
Es kann jetzt nicht mehr relevant sein, aber ich werde es hier lassen:
Und verwenden Sie es in Ihrer XML-Datei:
Es deaktiviert alle Benutzeraktionen und kann verwendet werden, wenn Sie BottomSheet nur programmgesteuert steuern möchten.
quelle
Überprüfen Sie den Status in der
onStateChanged
Methode,setBottomSheetCallback
wenn der Status lautet,BottomSheetBehavior.STATE_DRAGGING
und ändern Sie ihn aufBottomSheetBehavior.STATE_EXPANDED
diese Weise. Sie können ihnSTATE_DRAGGING
vom Benutzer anhalten . Wie untenVerwenden Sie die Taste, um das untere Blatt wie unten zu schließen
benutze nicht
setPeekHeight
oderapp:behavior_peekHeight
Auf diese Weise können Sie Ihr Ziel erreichen
quelle
BottomSheet View
match_parent
und wann immer ich versuche, es in meinemActivity
aufzurufen, habe ich bemerkt, dass es nach oben rutscht, aber es ist nicht sichtbar, bis ich auf dasEditText
drin tippe, dasKeyboard
dasBottomSheet View
STATE_SETTLING
. Ich habe eine Schaltfläche zum Öffnen und Schließen des unteren Blattes. Wenn es VERSTECKT ist, erweitere ich es. Wenn es ERWEITERT ist, verstecke ich es. Da es in SETTLING hängen bleibt, funktioniert meine Schaltfläche nach dem Ziehen des unteren Blattes nicht mehr. Irgendeine Idee dazu?Okay, die akzeptierte Antwort hat bei mir nicht funktioniert. Die Antwort von Виталий Обидейко inspirierte jedoch meine endgültige Lösung.
Zuerst habe ich das folgende benutzerdefinierte BottomSheetBehavior erstellt. Es überschreibt alle Berührungsmethoden und gibt false zurück (oder hat nichts getan), wenn es gesperrt ist. Andernfalls verhält es sich wie ein normales BottomSheetBehavior. Dies deaktiviert die Fähigkeit des Benutzers, nach unten zu ziehen, und hat keine Auswirkungen auf die Änderung des Status im Code.
LockableBottomSheetBehavior.java
Hier ist ein Beispiel für die Verwendung. In meinem Fall brauchte ich es, damit das untere Blatt beim Erweitern verriegelt wurde.
activity_home.xml
HomeActivity.java
Hoffe, das hilft, viel Verwirrung zu beseitigen!
quelle
Am Ende habe ich eine Problemumgehung geschrieben, um diesen Anwendungsfall des dynamischen Deaktivierens des Benutzer-Ziehens zu beheben, wobei BottomSheetBehavior in eine Unterklasse unterteilt wird, um onInterceptTouchEvent zu überschreiben und zu ignorieren, wenn ein benutzerdefiniertes Flag (in diesem Fall mAllowUserDragging) auf false gesetzt ist:
Und in Ihrem Layout xml:
Bisher ist dies die beständigste Lösung, um das Ziehen von Benutzern auf dem unteren Blatt bei Bedarf zu deaktivieren.
Alle anderen Lösungen, die darauf beruhten, einen weiteren setState-Aufruf im onStateChanged-Rückruf auszulösen, führten dazu, dass das BottomSheet in einen schlechten Zustand geriet oder erhebliche UX-Probleme verursachte (im Fall des Versendens des setState-Aufrufs in einer ausführbaren Datei).
Hoffe das hilft jemandem :)
Strahl
quelle
bottomSheetFragContainer.setNestedScrollingEnabled(false);
Späte Antwort, aber das hat bei mir funktioniert, was ein bisschen anders ist als das, was andere vorgeschlagen haben.
Sie könnten versuchen, die
cancelable
Eigenschaft auf false zu setzen, d. H.und dann manuell die Ereignisse behandeln, bei denen Sie den Dialog in der
setupDialog
Methode schließen möchten .Dies funktioniert mit einer ListView innerhalb des Dialogfragments, in der ich mich ein wenig mit anderen Lösungen beschäftigt habe.
quelle
event.isCanceled()
undevent.getAction() == MotionEvent.ACTION_UP
vor dem Schließen des Dialogfelds. Dadurch wird verhindert, dass Fehlklicks die Entlassung auslösen.Die akzeptierte Antwort funktioniert nicht auf dem ersten Testgerät, das ich verwende. Und der Rückprall ist nicht glatt. Es scheint besser, den Status erst auf STATE_EXPANDED zu setzen, nachdem ein Benutzer das Ziehen freigegeben hat. Folgendes ist meine Version:
quelle
Fügen Sie diesen Code dem BottomSheetBehavior- Objekt hinzu. Das Ziehen wird deaktiviert. Funktioniert gut für mich.
quelle
Erwartetes Verhalten:
Code:
quelle
Um das BottomSheet zu sperren und zu vermeiden, dass der Benutzer es herauswischt, habe ich Folgendes getan
Es funktioniert ganz gut für mich.
quelle
BottomSheetBehavior.STATE_HIDDEN
. In diesem Fall dürfen Sie auch nicht anrufensetPeekHeight()
. Dies ist hier viel weniger kompliziert als bei anderen Lösungen.Der einfache Weg, das Ziehen zu sperren, ist setPeekHeight, das der Ansichtshöhe entspricht. Beispielsweise:
quelle
Ein Beispiel mit BottomSheetDialogFragment. Es funktioniert perfekt.
Bearbeiten 09/04/2020: Ersetzt abgeschrieben
setBottomSheetCallback()
durchaddBottomSheetCallback()
quelle
Sie müssen nicht alle Ereignisse blockieren, wenn das untere Blatt deaktiviert ist. Sie können nur das Ereignis ACTION_MOVE blockieren. Verwenden Sie deshalb ein benutzerdefiniertes Verhalten für das untere Blatt
quelle
Hier ist eine funktionierende Version der Top-Lösung in Kotlin:
Wann immer Sie möchten:
Das
bottom_sheet_main
ist die aktuelle Ansicht mit Kotlin Android Erweiterungen .quelle
Setzen Sie bottomSheet onClickListener auf null.
Diese Zeile deaktiviert alle Aktionen nur für bottomSheet und wirkt sich nicht auf die innere Ansicht aus.
quelle
Sie können das Ziehen des BottomSheets wie folgt deaktivieren.
(Kotlin), ich hoffe, diese Antwort kann Ihr Problem lösen.
quelle
Ich habe eine erstaunliche Lösung gefunden. Das anfängliche Problem war, dass bottomSheet in den Status HIDDEN überging und dann nicht mehr in bottomSheetDialog.show () angezeigt wurde. Aber ich wollte den Dialog auf der show () -Methode sichtbar machen und dem Benutzer ermöglichen, ihn nach unten zu wischen, damit er sich wie ein unteres Blatt anfühlt. Unten ist was ich getan habe ..
quelle
BottomSheetDialog
in Ihr Projekt und benennen Sie es in umMyBottomSheetDialog
getBottomSheetBehavior
zuMyBottomSheetDialog
MyBottomSheetDialog
stattdessenBottomSheetDialog
Code wie dieser
in Ihrem Code
quelle
Dies ist im Grunde die Kotlin-Version der richtigen Antwort oben:
quelle
Versuche dies.
1) Erstellen Sie das untere Blatt und deklarieren Sie die Variable in Ihrer Java-Klasse wie
2)
sheetBehavior = BottomSheetBehavior.from(bottomSheet);
3) Fügen Sie in der Rückruffunktion des unteren Blattes die folgenden Zeilen hinzu.
quelle
Zuerst möchte ich mich nur bei allen bedanken, die versucht haben, eine Antwort zu geben. Ich schreibe nur diese Antwort, indem ich dieses Problem so löse, wie ich will. Ich werde Schritt für Schritt beschreiben, wie ich das mache, indem ich von hier aus Hilfe nehme.
Visualisierung: Nach dem Klicken auf die Schaltfläche sehen
Show BottomSheet
Sie den zweiten Bildschirm . Jetzt werden Sie sehen, dass BottomSheet nur zum Ziehen gesperrt ist . Aber wenn Sie auf die Schaltfläche Länderliste der BottomSheet wird verstecken. Dies war die Beschreibung, die wir jetzt in den Code einarbeiten.Fügen Sie zunächst die Designunterstützungsbibliothek zu Ihrer build.gradle- Datei hinzu:
UserLockBottomSheetBehavior.java : Bildnachweis : James Davis (Thanks Man)
quelle
Die Lösung aus der akzeptierten Antwort hat meistens für mich funktioniert, aber mit einem Problem: Ansichten, die sich hinter der Ansicht des unteren Blattes befinden, reagierten auf Berührungsereignisse, wenn ein Berührungsereignis im Bereich des unteren Blattes auftritt, der frei von untergeordneten Ansichten ist. Mit anderen Worten, wie Sie im Bild unten sehen können, reagiert die Karte darauf, wenn der Benutzer den Finger in das untere Blatt schiebt.
Um das Problem zu beheben, habe ich die
onInterceptTouchEvent
Methode durch FestlegentouchListener
in der unteren Blattansicht geändert (der Rest des Codes bleibt derselbe wie in der akzeptierten Lösung).quelle
Mit
'com.google.android.material:material:1.2.0-alpha06'
Funktioniert hervorragend mit
NestedScrollView
undRecyclerView
Beispielcode:
quelle
Das Anpassen des
peakHeight
Wertes hat bei mir funktioniert.quelle
quelle
Dies ist das erste Ergebnis in Google. Ich glaube, es ist nur fair, die einfache Lösung hier einzutragen:
und dann rufen Sie es einfach
onCreateView()
in derBottomSheetDialogFragment
Implementierung aufquelle
Ich habe das gleiche Problem in
BottomSheetDialogFragment
und wende viele Lösungen mit dembehavior
von an,dialog
aber keines davon löst mein Problem und dann habe ich es gelöst, abersetCancelable(false);
zum Zeitpunkt der Initialisierung von eingestelltdialog
.Dadurch wird die Geste deaktiviert
BottomSheetDialogFragment
und Sie können siedialog
mithilfe derdismiss();
Funktion programmgesteuert schließen .quelle
Ich hatte das gleiche Problem, ich habe dies durch Code gelöst. Der Benutzer kann kein Bottomheet ziehen. Sie müssen den Status programmgesteuert behandeln.
quelle
Verwenden Sie einfach:
bottomSheet.dismissOnDraggingDownSheet = false
Von der Material.io-Website kopiert:
let viewController: ViewController = ViewController() let bottomSheet: MDCBottomSheetController = MDCBottomSheetController(contentViewController: viewController)
// **** Diese Zeile verhindert das Entlassen durch Ziehen von bottomSheet ****
bottomSheet.dismissOnDraggingDownSheet = false
present(bottomSheet, animated: true, completion: nil)
quelle