studio sheet modal medium bottomsheetdialogfragment bottom bed android bottom-sheet

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