Ho implementato il comportamento del foglio di calcolo con NestedScrollView. E mi chiedevo se è possibile nascondere la vista del foglio di bottiglia quando viene toccata all'esterno.android BottomSheet come comprimere quando si fa clic all'esterno?
risposta
Finalmente sono stato in grado di fare questo,
utilizzate le seguenti righe di codice:
@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);
}
Funziona come un fascino! – galvan
e in Fragment? –
@RajeshNasit Implementare il metodo DispatchTouchEvent nella propria attività e utilizzare FragmentManager per chiamare il metodo nel frammento. –
Ci sono molti popoli a trovare un modo per implementare dispatchTouchEvent sul frammento. Quindi, ecco come si può fare questo:
creare un layout personalizzato come definito:
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);
}
}
Ora usare questa disposizione come base del layout frammento. Frammento interno inizializza questo layout come:
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);
}
}
}
}
Grazie all'OP per la domanda/risposta. Ho usato il suo codice ma ho migliorato la sua pulizia e ho voluto condividerlo. Invece di estendere una vista e aggiungere l'interfaccia, è possibile codificarla direttamente in BottomSheetBehavior. Come questo:
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);
}
}
e quindi è sufficiente aggiungere al vostro file XML di layout:
<?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>
impostare un click sul listener per il layout principale (coordinate layout in questo caso)
@OnClick(R.id.coordinateLayout)
public void onClickView(View view) {
if (sheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
sheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
}
Nota: Butterknife è utilizzato per il clic altrimenti utilizzare il codice belo w in onCreate dell'attività.
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);
}
}
});
È una domanda con risposta automatica? Perché hai aggiunto domande e risposte nello stesso tempo, quindi ti stavo chiedendo. –
Sì, così che gli altri non si sentano frustrati se hanno lo stesso problema. –