Estou tentando desativar o recurso de arrastar do usuário BottomSheet
. O motivo pelo qual desejo desativar são duas coisas. 1. Está impedindo que o ListView
role para baixo, 2. Não quero que os usuários descartem arrastando, mas com um botão no BottomSheetView
. Isso é o que eu fiz
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;
}
}
});
}
});
O 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
fonte
fonte
Respostas:
Agora pode não ser mais relevante, mas vou deixá-lo aqui:
E use-o em seu arquivo xml:
Ele desativa todas as ações do usuário e pode ser usado quando você deseja controlar BottomSheet apenas de forma programática.
fonte
verifique o estado no
onStateChanged
método desetBottomSheetCallback
se o estado é,BottomSheetBehavior.STATE_DRAGGING
então altere-o paraBottomSheetBehavior.STATE_EXPANDED
que você possa interromperSTATE_DRAGGING
pelo usuário. como abaixouse o botão para abrir e fechar a folha inferior como abaixo
não use
setPeekHeight
ouapp:behavior_peekHeight
pelo caminho acima você pode alcançar seu objetivo
fonte
BottomSheet View
match_parent
e sempre que tento trazê-lo para o meuActivity
, notei que ele desliza para cima, mas não é visível até que eu toqueEditText
nele, o que traz oKeyboard
e torna oBottomSheet View
visívelSTATE_SETTLING
. Eu tenho um botão para abrir e fechar a folha inferior, se estiver OCULTO, eu o expande. Se estiver EXPANDIDO, eu oculto. Como ele fica preso em SETTLING, meu botão não funciona depois de arrastar a folha inferior. Alguma ideia disso?Tudo bem, então a resposta aceita não funcionou para mim. No entanto, a resposta de Виталий Обидейко inspirou minha solução final.
Primeiro, criei o seguinte BottomSheetBehavior personalizado. Ele substitui todos os métodos que envolvem toque e retorna falso (ou não fez nada) se estiver bloqueado. Caso contrário, ele atua como um BottomSheetBehavior normal. Isso desativa a capacidade do usuário de arrastar para baixo e não afeta a alteração do estado no código.
LockableBottomSheetBehavior.java
Aqui está um exemplo de como usá-lo. No meu caso, eu precisava para que a Folha Inferior travasse quando expandida.
activity_home.xml
HomeActivity.java
Espero que isso ajude a esclarecer grande parte da confusão!
fonte
Acabei escrevendo uma solução alternativa para abordar este caso de uso de desabilitar dinamicamente o arrastar do usuário, em que BottomSheetBehavior é uma subclasse para substituir onInterceptTouchEvent e para ignorá-lo quando um sinalizador personalizado (neste caso mAllowUserDragging) é definido como falso:
E em seu layout xml:
Até agora, esta é a solução de comportamento mais consistente para desativar o usuário arrastar na folha inferior sob demanda.
Todas as outras soluções que dependiam do disparo de outra chamada setState no retorno de chamada onStateChanged resultaram em um estado ruim do BottomSheet ou causaram problemas significativos de UX (no caso de postar a chamada setState em um Runnable).
Espero que isso ajude alguém :)
Raio
fonte
bottomSheetFragContainer.setNestedScrollingEnabled(false);
Resposta tardia, mas, isso é o que funcionou para mim, o que é um pouco diferente do que outros sugeriram.
Você pode tentar definir a
cancelable
propriedade como falsa, ou seja,e, em seguida, manipular manualmente os eventos em que deseja descartar o diálogo no
setupDialog
método.Isso funciona com um ListView dentro do fragmento de diálogo, que era onde eu estava ficando um pouco preso com outras soluções.
fonte
event.isCanceled()
eevent.getAction() == MotionEvent.ACTION_UP
antes de descartar o diálogo - isso vai impedir mis-cliques de disparar a demissão.A resposta aceita não funciona no primeiro dispositivo de teste que uso. E a recuperação não é suave. Parece melhor definir o estado para STATE_EXPANDED somente depois que o usuário soltar o recurso de arrastar. O seguinte é minha versão:
fonte
Adicione este código ao objeto BottomSheetBehavior . Arrastar será desativado. Funciona bem para mim.
fonte
Comportamento esperado:
Código:
fonte
Para bloquear a BottomSheet e evitar que o usuário a deslize, foi o que fiz
Funciona muito bem para mim.
fonte
BottomSheetBehavior.STATE_HIDDEN
. Nesse caso, você também não deve ligarsetPeekHeight()
. Isso é muito menos complicado do que outras soluções aqui.A maneira fácil de travar o arrasto é setPeekHeight igual à altura da vista. Por exemplo:
fonte
Uma amostra com BottomSheetDialogFragment. Funciona perfeitamente.
Editar 09/04/2020: Substituído depreciado
setBottomSheetCallback()
poraddBottomSheetCallback()
fonte
Você não precisa bloquear todos os eventos quando a folha inferior está desativada. Você pode bloquear apenas eventos ACTION_MOVE. É por isso que usar um comportamento personalizado de folha inferior como este
fonte
Esta é uma versão funcional da principal solução em Kotlin:
Então, sempre que você quiser usar:
Esta
bottom_sheet_main
é a visualização real usando as extensões Kotlin do Android .fonte
defina bottomSheet onClickListener como null.
esta linha desabilita todas as ações apenas sobre bottomSheet e não tem efeito na visualização interna.
fonte
você pode desativar o arrastamento da BottomSheet desta forma.
(kotlin), espero que esta resposta possa resolver seu problema.
fonte
Eu encontrei uma solução incrível. O problema inicial era quando bottomSheet ia para o estado HIDDEN e não aparecia em bottomSheetDialog.show (). Mas eu queria tornar a caixa de diálogo visível no método show () e também permitir que o usuário deslizasse para baixo de forma que parecesse a folha de baixo. Abaixo está o que eu fiz ..
fonte
BottomSheetDialog
para o seu projeto e renomeie paraMyBottomSheetDialog
getBottomSheetBehavior
aMyBottomSheetDialog
MyBottomSheetDialog
invésBottomSheetDialog
código como este
no seu código
fonte
Esta é basicamente a versão kotlin da resposta certa no topo:
fonte
Experimente isso.
1) Crie a folha de baixo e declare a variável em sua classe java como
2)
sheetBehavior = BottomSheetBehavior.from(bottomSheet);
3) Na função de retorno de chamada da folha inferior, adicione as seguintes linhas.
fonte
A princípio, só quero agradecer a todos que tentaram dar uma resposta. Estou apenas escrevendo esta resposta, resolvendo este problema como desejo. Vou descrever como faço isso passo a passo, obtendo ajuda daqui.
Visualização: Após clicar no Botão
Show BottomSheet
você verá a segunda tela . Agora você verá que BottomSheet está bloqueado apenas para arrastar . Mas se você clicar na Lista de Países, a Folha Inferior será ocultada. Essa foi a descrição agora vamos nos aprofundar no Código.Em primeiro lugar, adicione a biblioteca de suporte de design ao seu arquivo build.gradle :
UserLockBottomSheetBehavior.java : Crédito: James Davis (obrigado, cara)
fonte
A solução da resposta aceita funcionou principalmente para mim, mas com um problema: as visualizações, que estão atrás da visualização da folha inferior, começaram a reagir aos eventos de toque, se o evento de toque estiver acontecendo na área da folha inferior, que está livre de visualizações secundárias. Em outras palavras, como você pode ver na imagem abaixo, quando o usuário desliza o dedo dentro da folha inferior, o mapa começa a reagir sobre ela.
Para corrigir o problema, modifiquei o
onInterceptTouchEvent
método configurandotouchListener
a visualização da folha inferior (o resto do código permanece o mesmo da solução aceita).fonte
Com
'com.google.android.material:material:1.2.0-alpha06'
Funciona muito bem com
NestedScrollView
eRecyclerView
Código de exemplo:
fonte
Ajustar o
peakHeight
valor funcionou para mim.fonte
fonte
este é o primeiro resultado no google, então acredito que é justo colocar a solução simples aqui:
e do que apenas chamá-lo
onCreateView()
naBottomSheetDialogFragment
implementaçãofonte
Eu tenho o mesmo problema
BottomSheetDialogFragment
e aplico muitas soluções usando obehavior
dedialog
mas nenhuma resolveu meu problema e então resolvi mas configurandosetCancelable(false);
no momento da inicialização dedialog
.Isso desativará o gesto
BottomSheetDialogFragment
e você pode dispensardialog
programaticamente usando adismiss();
função.fonte
Eu tive o mesmo problema, resolvi isso por código. Não permite que o usuário arraste a folha inferior. você precisa lidar com o estado programaticamente.
fonte
Basta usar:
bottomSheet.dismissOnDraggingDownSheet = false
Copiado do site Material.io:
let viewController: ViewController = ViewController() let bottomSheet: MDCBottomSheetController = MDCBottomSheetController(contentViewController: viewController)
// **** Esta linha evita dispensar arrastando bottomSheet ****
bottomSheet.dismissOnDraggingDownSheet = false
present(bottomSheet, animated: true, completion: nil)
fonte