2016-07-04 16 views
15

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?

+0

È una domanda con risposta automatica? Perché hai aggiunto domande e risposte nello stesso tempo, quindi ti stavo chiedendo. –

+1

Sì, così che gli altri non si sentano frustrati se hanno lo stesso problema. –

risposta

20

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); 
} 
+0

Funziona come un fascino! – galvan

+3

e in Fragment? –

+1

@RajeshNasit Implementare il metodo DispatchTouchEvent nella propria attività e utilizzare FragmentManager per chiamare il metodo nel frammento. –

0

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); 
    } 
    } 

    } 

} 
0

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> 
0

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); 
     } 
    } 
}); 
Problemi correlati