Próbuję wyłączyć przeciąganie użytkownika BottomSheet
. Powodem, dla którego chcę wyłączyć, są dwie rzeczy. 1. Zapobiega ListView
przewijaniu w dół, 2. Nie chcę, aby użytkownicy zamykali za pomocą przeciągania, ale za pomocą przycisku na BottomSheetView
. Oto, co zrobiłem
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;
}
}
});
}
});
Plik 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>
Odpowiedzi:
To może być już nieaktualne, ale zostawię to tutaj:
I użyj go w swoim pliku xml:
Wyłącza wszystkie akcje użytkowników, może być używany, gdy chcesz sterować arkuszem dolnym tylko programowo.
źródło
sprawdź stan w
onStateChanged
metodziesetBottomSheetCallback
if state toBottomSheetBehavior.STATE_DRAGGING
zmień to tak, abyBottomSheetBehavior.STATE_EXPANDED
użytkownik mógł zatrzymaćSTATE_DRAGGING
. jak poniżejużyj przycisku, aby otworzyć zamknij dolny arkusz, jak poniżej
nie używaj
setPeekHeight
lubapp:behavior_peekHeight
powyższym sposobem możesz osiągnąć swój cel
źródło
BottomSheet View
match_parent
i za każdym razem, gdy próbuję go przywołać,Activity
zauważyłem, że przesuwa się w górę, ale nie jest widoczny, dopóki nieEditText
Keyboard
BottomSheet View
STATE_SETTLING
. Mam przycisk do otwierania i zamykania dolnego arkusza, jeśli jest UKRYTY, rozwijam go. Jeśli jest ROZSZERZONY, ukrywam to. Ponieważ utknął w ROZLICZENIU, mój przycisk nie działa po przeciągnięciu dolnego arkusza. Masz jakiś pomysł na to?W porządku, więc zaakceptowana odpowiedź nie działa dla mnie. Jednak odpowiedź Виталий Обидейко zainspirowała moje ostateczne rozwiązanie.
Najpierw utworzyłem następujący niestandardowy BottomSheetBehavior. Zastępuje wszystkie metody związane z dotykiem i zwraca fałsz (lub nic nie zrobił), jeśli jest zablokowany. W przeciwnym razie zachowuje się jak normalne zachowanie BottomSheetBehavior. To wyłącza możliwość przeciągania w dół przez użytkownika i nie wpływa na zmianę stanu w kodzie.
LockableBottomSheetBehavior.java
Oto przykład, jak go używać. W moim przypadku potrzebowałem tego, aby arkusz dolny zablokował się po rozwinięciu.
activity_home.xml
HomeActivity.java
Mam nadzieję, że pomoże to wyjaśnić wiele zamieszania!
źródło
Skończyło się na napisaniu obejścia, aby rozwiązać ten przypadek użycia dynamicznego wyłączania przeciągania użytkownika, w którym BottomSheetBehavior jest podklasą, aby zastąpić onInterceptTouchEvent i zignorować go, gdy niestandardowa flaga (w tym przypadku mAllowUserDragging) jest ustawiona na false:
A w pliku XML układu:
Jak dotąd jest to najbardziej konsekwentne rozwiązanie do wyłączania przeciągania użytkownika na dolnym arkuszu na żądanie.
Wszystkie inne rozwiązania, które polegały na wywołaniu innego wywołania setState w wywołaniu zwrotnym onStateChanged, spowodowały, że BottomSheet przeszedł w zły stan lub spowodowało poważne problemy z UX (w przypadku opublikowania wywołania setState w Runnable).
Mam nadzieję, że to komuś pomoże :)
Promień
źródło
bottomSheetFragContainer.setNestedScrollingEnabled(false);
Późna odpowiedź, ale to właśnie zadziałało w moim przypadku, co różni się nieco od tego, co sugerowali inni.
Możesz spróbować ustawić
cancelable
właściwość na false, tja następnie ręcznie obsługiwać zdarzenia, w których chciałbyś zamknąć okno dialogowe w
setupDialog
metodzie.Działa to z ListView wewnątrz fragmentu okna dialogowego, w którym utknąłem trochę z innymi rozwiązaniami.
źródło
event.isCanceled()
ievent.getAction() == MotionEvent.ACTION_UP
przed jego zamknięciem - zapobiegnie to błędnym kliknięciom wywołującym odrzucenie.Zaakceptowana odpowiedź nie działa na pierwszym urządzeniu testowym, którego używam. A odbicie nie jest gładkie. Wydaje się, że lepiej ustawić stan na STATE_EXPANDED tylko wtedy, gdy użytkownik zwolni przeciąganie. Oto moja wersja:
źródło
Dodaj ten kod do obiektu BottomSheetBehavior . Przeciąganie zostanie wyłączone. U mnie działa dobrze.
źródło
Spodziewane zachowanie:
Kod:
źródło
Aby zablokować arkusz dolny i uniknąć przeciągnięcia go przez użytkownika, oto co zrobiłem
U mnie działa całkiem nieźle.
źródło
BottomSheetBehavior.STATE_HIDDEN
. W takim przypadku nie możesz również dzwonićsetPeekHeight()
. Jest to znacznie mniej skomplikowane niż inne rozwiązania tutaj.Łatwy sposób na zablokowanie przeciągania jest ustawiony tak samo jak wysokość widoku. Na przykład:
źródło
Przykład z BottomSheetDialogFragment. Działa doskonale.
Edit 4.09.2020: Zastąpiony amortyzowane
setBottomSheetCallback()
zaddBottomSheetCallback()
źródło
Nie musisz blokować wszystkich wydarzeń, gdy dolny arkusz jest wyłączony. Możesz zablokować tylko wydarzenie ACTION_MOVE. Dlatego użyj takiego niestandardowego zachowania dolnego arkusza
źródło
Oto działająca wersja najlepszego rozwiązania w Kotlinie:
Wtedy, kiedy chcesz użyć:
To
bottom_sheet_main
jest rzeczywisty widok przy użyciu rozszerzeń Kotlin dla Androida .źródło
ustaw bottomSheet onClickListener na null.
ta linia wyłącza wszystkie działania dotyczące tylko arkusza dolnego i nie wpływa na widok wewnętrzny.
źródło
możesz wyłączyć przeciąganie arkusza dolnego w ten sposób.
(kotlin), mam nadzieję, że ta odpowiedź może rozwiązać twój problem.
źródło
Znalazłem świetne rozwiązanie. Początkowy problem polegał na tym, że bottomSheet przechodził w stan HIDDEN, a następnie nie pojawiał się w bottomSheetDialog.show (). Ale chciałem, aby okno dialogowe było widoczne w metodzie show (), a także chciałem umożliwić użytkownikowi przesunięcie go w dół, aby wyglądało jak dolny arkusz. Poniżej przedstawiam to, co zrobiłem ...
źródło
BottomSheetDialog
do swojego projektu i zmień nazwę naMyBottomSheetDialog
getBottomSheetBehavior
doMyBottomSheetDialog
MyBottomSheetDialog
zamiast tegoBottomSheetDialog
kod taki jak ten
w swoim kodzie
źródło
To jest w zasadzie wersja kotlin poprawnej odpowiedzi u góry:
źródło
Spróbuj tego.
1) Utwórz dolny arkusz i zadeklaruj zmienną w swojej klasie java, takiej jak
2)
sheetBehavior = BottomSheetBehavior.from(bottomSheet);
3) W funkcji wywołania zwrotnego w dolnej części arkusza dodaj następujące wiersze.
źródło
Na początku chcę tylko podziękować wszystkim, którzy próbowaliście udzielić odpowiedzi. Po prostu piszę tę odpowiedź, rozwiązując ten problem, jak chcę. Opiszę, jak robię to krok po kroku, korzystając z pomocy tutaj.
Wizualizacja: Po kliknięciu przycisku
Show BottomSheet
zobaczysz drugi ekran . Teraz zobaczysz, że BottomSheet jest po prostu zablokowany do przeciągania . Ale jeśli klikniesz na listę krajów, arkusz dolny zostanie ukryty . Taki był opis, teraz zajmijmy się Kodeksem.Najpierw dodaj bibliotekę obsługi projektowania do pliku build.gradle :
UserLockBottomSheetBehavior.java : Źródło : James Davis (dziękuję)
źródło
Rozwiązanie z zaakceptowanej odpowiedzi zadziałało w większości dla mnie, ale z jednym problemem: widoki, które znajdują się za dolnym widokiem arkusza, zaczęły reagować na zdarzenia dotykowe, jeśli zdarzenie dotykowe ma miejsce na obszarze dolnego arkusza, który jest wolny od widoków dziecka. Innymi słowy, jak widać na poniższym obrazku, gdy użytkownik wsunie palec w dolny arkusz, mapa zaczyna na niego reagować.
Aby rozwiązać problem, zmodyfikowałem
onInterceptTouchEvent
metodę, ustawiająctouchListener
widok dolnego arkusza (reszta kodu pozostaje taka sama jak w przyjętym rozwiązaniu).źródło
Z
'com.google.android.material:material:1.2.0-alpha06'
Działa świetnie z
NestedScrollView
iRecyclerView
Przykładowy kod:
źródło
Dostosowanie
peakHeight
wartości zadziałało dla mnie.źródło
źródło
to pierwszy wynik w google, więc uważam, że sprawiedliwe jest umieszczenie tutaj prostego rozwiązania:
a nie tylko wywoływać to z
onCreateView()
poziomuBottomSheetDialogFragment
implementacjiźródło
Mam ten sam problem
BottomSheetDialogFragment
i stosuję wiele rozwiązań przy użyciubehavior
of,dialog
ale żadne z nich nie rozwiązuje mojego problemu, a następnie rozwiązałem go, ale ustawiającsetCancelable(false);
w momencie inicjalizacjidialog
.Spowoduje to wyłączenie gestu włączania
BottomSheetDialogFragment
i możesz odrzucićdialog
programowo za pomocądismiss();
funkcji.źródło
Miałem ten sam problem, rozwiązałem go kodem. Nie pozwoli użytkownikowi na przeciąganie arkusza dolnego. musisz obsługiwać stan programowo.
źródło
Po prostu użyj:
bottomSheet.dismissOnDraggingDownSheet = false
Skopiowano ze strony Material.io:
let viewController: ViewController = ViewController() let bottomSheet: MDCBottomSheetController = MDCBottomSheetController(contentViewController: viewController)
// **** Ta linia zapobiega odrzuceniu przez przeciągnięcie dolnego arkusza ****
bottomSheet.dismissOnDraggingDownSheet = false
present(bottomSheet, animated: true, completion: nil)
źródło