Я пытаюсь отключить перетаскивание пользователя BottomSheet
. Причина, по которой я хочу отключить - две вещи. 1. Это предотвращает ListView
прокрутку вниз, 2. Я не хочу, чтобы пользователи увольняли с помощью перетаскивания, но с помощью кнопки на BottomSheetView
. Это то, что я сделал
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;
}
}
});
}
});
The 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>
Ответы:
Возможно, сейчас это уже не актуально, но я оставлю это здесь:
И используйте его в своем xml файле:
Он отключает все действия пользователей, его можно использовать, когда вы хотите управлять BottomSheet только программно.
источник
проверьте состояние в
onStateChanged
методеsetBottomSheetCallback
if state,BottomSheetBehavior.STATE_DRAGGING
затем измените егоBottomSheetBehavior.STATE_EXPANDED
таким образом, чтобы пользователь мог остановитьSTATE_DRAGGING
его. как показано нижеиспользуйте кнопку, чтобы открыть нижний лист, как показано ниже
не используйте
setPeekHeight
илиapp:behavior_peekHeight
указанным выше способом вы можете достичь своей цели
источник
BottomSheet View
match_parent
и всякий раз, когда я пытался поднять его в своем,Activity
я замечал, что он скользит вверх, но его не видно, пока я неEditText
Keyboard
BottomSheet View
STATE_SETTLING
. У меня есть кнопка для открытия и закрытия нижнего листа, если она СКРЫТА, разворачиваю. Если он РАСШИРЕН, я его прячу. Поскольку он застревает в SETTLING, моя кнопка не работает после перетаскивания нижнего листа. Есть идеи по этому поводу?Хорошо, принятый ответ мне не подошел. Однако ответ Виталий Обидейко вдохновил мое окончательное решение.
Сначала я создал следующий пользовательский BottomSheetBehavior. Он отменяет все методы, связанные с касанием, и возвращает false (или ничего не делал), если он заблокирован. В противном случае он действует как обычный BottomSheetBehavior. Это отключает возможность пользователя перетаскивать вниз и не влияет на изменение состояния в коде.
LockableBottomSheetBehavior.java
Вот пример того, как его использовать. В моем случае это было нужно, чтобы нижний лист блокировался при раскрытии.
activity_home.xml
HomeActivity.java
Надеюсь, это поможет устранить большую путаницу!
источник
Я закончил тем, что написал обходной путь для решения этого варианта использования динамического отключения перетаскивания пользователя, в соответствии с которым BottomSheetBehavior является подклассом для переопределения onInterceptTouchEvent и игнорирования его, когда настраиваемый флаг (в данном случае mAllowUserDragging) установлен в false:
И в вашем макете xml:
Пока что это наиболее стабильное решение для отключения перетаскивания пользователем на нижний лист по требованию.
Все другие решения, которые полагались на запуск другого вызова setState в обратном вызове onStateChanged, приводили к тому, что BottomSheet попадал в плохое состояние или вызывали значительные проблемы UX (в случае публикации вызова setState в Runnable).
Надеюсь, это кому-то поможет :)
Рэй
источник
bottomSheetFragContainer.setNestedScrollingEnabled(false);
Поздний ответ, но это то, что сработало для меня, что немного отличается от того, что предлагали другие.
Вы можете попробовать установить для
cancelable
свойства значение false, т.е.а затем вручную обрабатывать события, в которых вы хотите закрыть диалоговое окно в
setupDialog
методе.Это работает с ListView внутри фрагмента диалогового окна, в котором я немного застревал с другими решениями.
источник
event.isCanceled()
иevent.getAction() == MotionEvent.ACTION_UP
перед закрытием диалогового окна - это предотвратит отклонение от ошибочных щелчков.Принятый ответ не работает на первом используемом мной тестовом устройстве. И возврат в норму не бывает плавным. Кажется, лучше установить состояние STATE_EXPANDED только после того, как пользователь отпустит перетаскивание. Вот моя версия:
источник
Добавьте этот код в объект BottomSheetBehavior . Перетаскивание будет отключено. У меня отлично работает.
источник
Ожидаемое поведение:
Код:
источник
Чтобы заблокировать BottomSheet и избежать того, чтобы пользователь смахнул его, вот что я сделал
У меня это работает очень хорошо.
источник
BottomSheetBehavior.STATE_HIDDEN
. В таком случае звонить также нельзяsetPeekHeight()
. Здесь это намного проще, чем другие решения.Простой способ заблокировать перетаскивание - setPeekHeight такой же, как высота просмотра. Например:
источник
Пример с BottomSheetDialogFragment. Работает отлично.
Изменить 09/04/2020: заменено устаревшим
setBottomSheetCallback()
наaddBottomSheetCallback()
источник
Вам не нужно блокировать все события, когда нижний лист отключен. Вы можете заблокировать только событие ACTION_MOVE. Вот почему используйте настраиваемое поведение нижнего листа, подобное этому
источник
Вот рабочая версия топового решения в Kotlin:
Затем, когда вы захотите использовать:
Это
bottom_sheet_main
фактическое представление с использованием Kotlin Android Extensions .источник
установите для bottomSheet onClickListener значение null.
эта строка отключает все действия только с bottomSheet и не влияет на внутренний вид.
источник
вы можете отключить перетаскивание BottomSheet вот так.
(Котлин), надеюсь, этот ответ поможет решить вашу проблему.
источник
Я нашел удивительное решение. Первоначальная проблема заключалась в том, что когда bottomSheet переходил в состояние HIDDEN, тогда он не отображался в bottomSheetDialog.show (). Но я хотел, чтобы диалог был видимым в методе show (), а также хотел, чтобы пользователь мог смахивать его вниз, чтобы он выглядел как нижний лист. Ниже то, что я сделал ..
источник
BottomSheetDialog
в свой проект и переименуйте вMyBottomSheetDialog
getBottomSheetBehavior
кMyBottomSheetDialog
MyBottomSheetDialog
вместоBottomSheetDialog
код вроде этого
в вашем коде
источник
Это, по сути, котлинская версия правильного ответа вверху:
источник
С участием
'com.google.android.material:material:1.2.0-alpha06'
Отлично работает с
NestedScrollView
иRecyclerView
Пример кода:
источник
Попробуй это.
1) Создайте нижний лист и объявите переменную в своем классе Java, например
2)
sheetBehavior = BottomSheetBehavior.from(bottomSheet);
3) В функцию обратного вызова нижнего листа добавьте следующие строки.
источник
Сначала я просто хочу поблагодарить всех, кто пытался дать ответ. Я просто пишу этот ответ, решая эту проблему, как хочу. Я собираюсь описать, как я это делаю, шаг за шагом, воспользовавшись помощью здесь.
Визуализация: после нажатия на кнопку
Show BottomSheet
вы увидите второй экран . Теперь вы увидите, что BottomSheet просто заблокирован для перетаскивания . Но если вы нажмете на Список стран, BottomSheet скроется. Это было описание, теперь давайте углубимся в Кодекс.Сначала добавьте библиотеку поддержки дизайна в файл build.gradle :
UserLockBottomSheetBehavior.java : Предоставлено : Джеймс Дэвис (спасибо, человек)
источник
Решение из принятого ответа в основном сработало для меня, но с одной проблемой: представления, которые находятся за представлением нижнего листа, начали реагировать на события касания, если событие касания происходит в области нижнего листа, которая свободна от дочерних представлений. Другими словами, как вы можете видеть на изображении ниже, когда пользователь перемещает палец внутрь нижнего листа, карта начинает реагировать на это.
Чтобы решить эту проблему, я изменил
onInterceptTouchEvent
метод, установив видtouchListener
снизу листа (остальной код остается таким же, как в принятом решении).источник
Изменение
peakHeight
значения сработало для меня.источник
источник
это первый результат в Google, поэтому я считаю, что будет справедливо поместить здесь простое решение:
а не просто вызвать его из
onCreateView()
вBottomSheetDialogFragment
реализацииисточник
У меня такая же проблема,
BottomSheetDialogFragment
и я применяю многие решения с использованиемbehavior
of,dialog
но ни одно из них не решает мою проблему, и затем я решил ее, но установилsetCancelable(false);
во время инициализацииdialog
.Это отключит жест,
BottomSheetDialogFragment
и вы можетеdialog
программно закрыть его с помощьюdismiss();
функции.источник
У меня была такая же проблема, я решил ее с помощью кода. Это не позволит пользователю перетаскивать нижний лист. вам нужно обрабатывать состояние программно.
источник
Просто используйте:
bottomSheet.dismissOnDraggingDownSheet = false
Скопировано с сайта Material.io:
let viewController: ViewController = ViewController() let bottomSheet: MDCBottomSheetController = MDCBottomSheetController(contentViewController: viewController)
// **** Эта строка предотвращает удаление путем перетаскивания bottomSheet ****
bottomSheet.dismissOnDraggingDownSheet = false
present(bottomSheet, animated: true, completion: nil)
источник