2016-02-25 12 views
22

Voglio provare BottomSheetDialog introdotto nella libreria di supporto Android 23.2 ma non sembra funzionare correttamente. Ecco ciò che il dottore dice:Come utilizzare BottomSheetDialog?

Mentre BottomSheetBehavior cattura caso lenzuolo di sotto persistente, questa versione offre anche un BottomSheetDialog e BottomSheetDialogFragment per riempire i fogli inferiori modali caso d'uso. Sostituire semplicemente AppCompatDialog o AppCompatDialogFragment con gli equivalenti del foglio inferiore per avere la finestra di dialogo come foglio in basso . "

Così ho cambiato la mia AppCompatDialog a BottomSheetDialog:

package my.package.ui.dialog; 

import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.support.design.widget.BottomSheetDialog; 

import my.package.R; 

public class AccountActionsDialog extends BottomSheetDialog { 
    public AccountActionsDialog(Context context) { 
     super(context); 

     if (context instanceof Activity) { 
      setOwnerActivity((Activity) context); 
     } 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(getLayoutInflater().inflate(R.layout.dialog_account_actions, null)); 
    } 
} 

Ecco il mio file di layout:

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical"> 

    <TextView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:background="#ff0000" 
     android:padding="16dp" 
     android:text="Delete account" 
     android:textColor="#ffffff" /> 

</LinearLayout> 

Poi ho utilizzare il seguente codice nella mia attività:

new AccountActionsDialog(this).show(); 

Lo schermo si oscura ma il contenuto della mia finestra di dialogo non è visibile. Qualche idea su cosa potrebbe mancare? Funziona bene quando uso invece AppCompatDialog.

+0

C'è un motivo particolare non si utilizza 'setContentView (R.layout.dialog_account_actions)'? – ianhanniballake

+0

Sì. Inizialmente ho gonfiato la vista radice e ho utilizzato findViewById() per trovare tutti i sottoview di cui ho bisogno e impostare i listener appropriati per loro. Ho semplificato il codice per questo esempio e ho dimenticato di cambiare questa parte. Il problema rimane, indipendentemente dal modo in cui è impostato il layout. –

+0

Questo è sicuramente un bug nella libreria di supporto - per favore archivene uno su b.android.com con un piccolo progetto di esempio e includi un link qui così posso portarlo in squadra - per un comportamento ancora più pazzo - imposta il tuo ' LinearLayout' ad un'altezza di ~ 250 dpi. – ianhanniballake

risposta

2

Questo è il file di layout di BottomSheetDialog.

<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:soundEffectsEnabled="false"> 

<FrameLayout 
     android:id="@+id/design_bottom_sheet" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal" 
     app:layout_behavior="@string/bottom_sheet_behavior" 
     style="?attr/bottomSheetStyle"/> 

</android.support.design.widget.CoordinatorLayout> 

La vista contenuto è all'interno della vista design_bottom_sheet, sarà posizionato verticalmente da centro CoordinatorLayout, e BottomSheetBehavior compenserà esso.

mParentHeight = parent.getHeight(); 
mMinOffset = Math.max(0, mParentHeight - child.getHeight()); 
mMaxOffset = mParentHeight - mPeekHeight; 
if (mState == STATE_EXPANDED) { 
    ViewCompat.offsetTopAndBottom(child, mMinOffset); 
} else if (mHideable && mState == STATE_HIDDEN) { 
    ViewCompat.offsetTopAndBottom(child, mParentHeight); 
} else if (mState == STATE_COLLAPSED) { 
    ViewCompat.offsetTopAndBottom(child, mMaxOffset); 
} 

E intented a Positon design_bottom_sheet a mMaxOffset, ma in realtà il getTop iniziale della vista bambino non 0, ma (mParentHeight - childHeight)/2 è, in modo da visualizzare, se compensato più che l'offset desiderato.

Trova la vista design_bottom_sheet e imposta la gravità su Gravity.TOP | Gravity.CENTER_HORIZONTAL la risolverà. Tuttavia, se ChildHeight è inferiore a mPeekHeight, ci sarà un'area vuota sotto la vista del contenuto.

Tuttavia, se peekHeight > childHeight, il mMaxOffset sarà inferiore a mMinOffset, che causerà un comportamento strano.

Forse il codice deve essere modificato per

mMaxOffset = Math.max((mParentHeight - mPeekHeight), mMinOffset); 

invece di

mMaxOffset = mParentHeight - child.getHeight(); 
+0

Questo è il problema che sto vedendo anche io. Il Framelayout che avvolge la vista del contenuto è centrato verticalmente per qualche motivo. Quando BottomSheetBehavior espone Framelayout, inizia con un valore Y> 0. Tutta la matematica all'interno di quel comportamento è pensata per funzionare compensando la vista dal TOP del genitore, risultando che il contenuto è molto più basso del previsto (fuori dallo schermo) –

+0

@Edward Kimmel FrameLayout controllerà se si imposta la gravità in alto, in basso o in centro_vertical, se nessuno di questi è impostato, FrameLayout imposterà il figlio in alto. Tuttavia, 'CoordinatorLayout.layoutChild' usa' Gravity.apply' per impaginare i suoi figli, in 'Gravity.apply', se nessuno di questi valori di gravità è impostato, imposterà la visualizzazione figlio al centro del genitore. Vedi [Gravity.apply] (http://androidxref.com/6.0.1_r10/xref/frameworks/base/core/java/android/view/Gravity.java#231) –

2

stavo expriencing lo stesso problema, sfondo grigio e il contenuto non è visibile. Ecco come sono riuscito a risolvere il problema impostando la visualizzazione del contenuto nel metodo nascosto setupDialog().

public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment { 

    private TextView mOffsetText; 
    private TextView mStateText; 
    private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() { 

     @Override 
     public void onStateChanged(@NonNull View bottomSheet, int newState) { 
      setStateText(newState); 
      if (newState == BottomSheetBehavior.STATE_HIDDEN) { 
       dismiss(); 
      } 

     } 

     @Override 
     public void onSlide(@NonNull View bottomSheet, float slideOffset) { 
      setOffsetText(slideOffset); 
     } 
    }; 
    private LinearLayoutManager mLinearLayoutManager; 
    private ApplicationAdapter mAdapter; 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     return super.onCreateDialog(savedInstanceState); 
    } 

    @Override 
    public void onViewCreated(View contentView, @Nullable Bundle savedInstanceState) { 
     super.onViewCreated(contentView, savedInstanceState); 
    } 

    @Override 
    public void setupDialog(Dialog dialog, int style) { 
     super.setupDialog(dialog, style); 
     View contentView = View.inflate(getContext(), R.layout.bottom_sheet_dialog_content_view, null); 
     dialog.setContentView(contentView); 
     mBottomSheetBehavior = BottomSheetBehavior.from(((View) contentView.getParent())); 
     if (mBottomSheetBehavior != null) { 
      mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback); 
     } 
     mOffsetText = (TextView) contentView.findViewById(R.id.offsetText); 
     mStateText = (TextView) contentView.findViewById(R.id.stateText); 
    } 

} 

E il layout:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 


    <TextView 
     android:id="@+id/offsetText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textColor="@android:color/black" /> 

    <TextView 
     android:id="@+id/stateText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textColor="@android:color/black" /> 

    <TextView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 
</LinearLayout> 
+0

per ottenere un comportamento puoi anche usare BottomSheetBehavior.from (Vedi v) anche se genera eccezioni –

2

Ecco il problema su code.google.com https://code.google.com/p/android/issues/detail?id=201793

Un problema che alcuni utenti stanno vedendo riduce al FrameLayout che avvolge la nostra visione di contenuti essere centrato verticalmente. Il BottomSheetBehavior funziona solo se questa vista è allineata in alto. Non ho capito che cosa fa sì che il FrameLayout a diventare centrato ancora in verticale, ma ecco una possibile soluzione:

View contentView = ... 
// You may have to measure your content view first. 
dialog.setContentView(contentView); 

// Change this to a percentage or a constant, whatever you want to do. 
// The default is 1024 - any views smaller than this will be pulled off 
// the bottom of the screen. 
float peekHeight = contentView.getMeasuredHeight(); 

View parent = (View)contentView.getParent(); 
BottomSheetBehavior behavior = BottomSheetBehavior.from(parent); 
behavior.setPeekHeight(peekHeight); 
CoordinatorLayout.LayoutParams layoutParams = 
    (CoordinatorLayout.LayoutParams)parent.getLayoutParams(); 
layoutParams.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL; 
+0

Questo non risolve nulla. – 0101100101

0

E 'iniziato a lavorare quando ho impostato ad altezza fissa per il mio TextView (200dp), anche se per alcuni valori di altezza si comporta ancora in modo errato. Ovviamente è un problema di supporto alla lib. Ci sono già alcuni rapporti relativi alla BottomSheetDialog nel bug tracker:

https://code.google.com/p/android/issues/detail?id=201793&sort=-opened&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened

https://code.google.com/p/android/issues/detail?id=201826