android - modal - bottomsheetdialogfragment gradle
Android BottomSheet ¿cómo colapsar cuando se hace clic fuera? (6)
Establezca un oyente al hacer clic para su diseño principal (Diseño de coordenadas en este caso)
@OnClick(R.id.coordinateLayout)
public void onClickView(View view) {
if (sheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
Nota: Butterknife se usa para hacer clic en el botón; de lo contrario, use el código a continuación en onCreate de la actividad.
CoordinateLayout layout = (CoordinateLayout) findViewById(R.id. coordinateLayout);
layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (sheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
});
He implementado el comportamiento de la hoja inferior con NestedScrollView. Y me preguntaba si es posible ocultar la vista de la hoja inferior cuando se toca afuera.
Finalmente pude hacer esto,
Utiliza las siguientes líneas de código:
@Override public boolean dispatchTouchEvent(MotionEvent event){
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mBottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED) {
Rect outRect = new Rect();
bottomSheet.getGlobalVisibleRect(outRect);
if(!outRect.contains((int)event.getRawX(), (int)event.getRawY()))
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
return super.dispatchTouchEvent(event);
}
Gracias a la OP por la pregunta / respuesta. He usado su código pero he mejorado su limpieza y quería compartirlo. En lugar de extender una Vista y agregar la interfaz, puede codificar eso directamente en BottomSheetBehavior. Me gusta esto:
AutoCloseBottomSheetBehavior.java
import android.content.Context;
import android.graphics.Rect;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class AutoCloseBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
public AutoCloseBottomSheetBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN &&
getState() == BottomSheetBehavior.STATE_EXPANDED) {
Rect outRect = new Rect();
child.getGlobalVisibleRect(outRect);
if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
return super.onInterceptTouchEvent(parent, child, event);
}
}
y luego simplemente lo agrega a su diseño XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
... your normal content here ...
<SomeLayout... />
... the bottom sheet with the behavior
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_behavior="<com.package.name.of.the.class>.AutoCloseBottomSheetBehavior">
... the bottom sheet views
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
Hay muchas personas que encuentran una manera de implementar dispatchTouchEvent en el fragmento. Así que aquí está cómo pueden hacer esto:
crear un diseño personalizado como se define:
public class DispatchTouchEvent extends LinearLayout {
public interface onDispatchEvent
{
void dispatchEvent(MotionEvent e);
}
private onDispatchEvent dispatchEvent;
public DispatchTouchEvent(Context context) {
super(context);
}
public DispatchTouchEvent(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DispatchTouchEvent(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setDispatchEvent(onDispatchEvent dispatchEvent)
{
this.dispatchEvent=dispatchEvent;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if(dispatchEvent!=null)
{
dispatchEvent.dispatchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}
}
Ahora use este diseño como la base de su diseño de fragmentos. El fragmento interno inicializa este diseño como:
public class ABC extends fragment implements DispatchTouchEvent.onDispatchEvent
{
DispatchTouchEvent dispatchTouchEvent;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
....
dispatchTouchEvent = (DispatchTouchEvent)rootView.findViewById(R.id.dispatch_event);
dispatchTouchEvent.setDispatchEvent(this);
....
}
@Override
public void dispatchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mBottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED)
{
Rect outRect = new Rect();
bottomSheet.getGlobalVisibleRect(outRect);
if(!outRect.contains((int)event.getRawX(), (int)event.getRawY()))
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
}
}
Para la actividad:
@Override
public boolean dispatchTouchEvent(MotionEvent event){
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (mBottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED) {
Rect outRect = new Rect();
bottomSheet.getGlobalVisibleRect(outRect);
if(!outRect.contains((int)event.getRawX(), (int)event.getRawY()))
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
return super.dispatchTouchEvent(event);
}
Para Fragmento: Use el mismo método en la Actividad como,
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (fragment != null && fragment instanceof HomeFragment) {
((HomeFragment) fragment).hideBottomSheetFromOutSide(event);
}
}
return super.dispatchTouchEvent(event);
}
y Crear Método en Fragmento como:
/**
* Calling from Dashboard Activity
*
* @param event Motion Event
*/
public void hideBottomSheetFromOutSide(MotionEvent event) {
if (isBottomSheetMenuExpanded()) {
Rect outRect = new Rect();
mBinding.homeBottomSheetLayout.getGlobalVisibleRect(outRect);
if (!outRect.contains((int) event.getRawX(), (int) event.getRawY()))
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
Espero que te ayude.
Gracias.
someViewToClickOn.setOnClickListener(v ->
behavior.setState(BottomSheetBehavior.STATE_HIDDEN));
¡Esto funciona también! Primero utilicé BottomSheetBehavior.STATE_COLLAPSED
que no funciona