J'ai l'implémentation de feuille de fond de test suivante.
Lorsque j'ai défini peekHeight sur une valeur inférieure à 500, cela fonctionne. Après une certaine valeur, toute augmentation de la hauteur de l'aperçu ne changera pas la façon dont la feuille inférieure est développée. Il reste juste là pour ne faire glisser que manuellement. Comment définissons-nous le peekHeight par programme pour garantir que la feuille inférieure est automatiquement développée à la hauteur de l'aperçu.
bottom_sheet_dialog_main
<?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"
Android:id="@+id/locUXCoordinatorLayout"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<LinearLayout
Android:id="@+id/locUXView"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:fitsSystemWindows="true"
Android:orientation="vertical"
app:behavior_hideable="false"
app:behavior_peekHeight="0dp"
app:layout_behavior="@string/bottom_sheet_behavior">
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="1 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="2 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="3 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="4 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="5 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="6 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="7 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="8 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="9 Value" />
<TextView
Android:layout_width="match_parent"
Android:layout_height="100dp"
Android:text="First Value" />
</LinearLayout>
</Android.support.design.widget.CoordinatorLayout>
Code Java
public class MyBottomSheetDialogFragment extends BottomSheetDialogFragment {
private static BottomSheetBehavior bottomSheetBehavior;
private static View bottomSheetInternal;
private static MyBottomSheetDialogFragment INSTANCE;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
CoordinatorLayout coordinatorLayout = (CoordinatorLayout)d.findViewById(R.id.locUXCoordinatorLayout);
bottomSheetInternal = d.findViewById(R.id.locUXView);
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetInternal);
bottomSheetBehavior.setPeekHeight(bottomSheetInternal.getHeight());
bottomSheetInternal.requestLayout();
coordinatorLayout.getLayoutParams().height = bottomSheetInternal.getHeight();
Toast.makeText(getActivity(), "Height is" + bottomSheetInternal.getHeight() + " " + coordinatorLayout.getLayoutParams().height, Toast.LENGTH_LONG).show();
}
});
INSTANCE = this;
return inflater.inflate(R.layout.bottom_sheet_dialog_main, container, false);
}
}
Par une inspection plus approfondie de l'interface utilisateur, nous constatons qu'il existe un autre CoordinatorLayout
qui enveloppe notre disposition de coordinateur. Le parent CoordinatorLayout
a un FrameLayout
avec un BottomSheetBehavior
avec l'id design_bottom_sheet
. La hauteur d'aperçu définie à partir de notre code ci-dessus devenait contrainte en raison de match_parent
hauteur du FrameLayout
avec l'id design_bottom_sheet
En définissant la hauteur de l'aperçu de FrameLayout
avec l'id design_bottom_sheet, ce problème a été résolu
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
coordinatorLayout = (CoordinatorLayout) d.findViewById(R.id.locUXCoordinatorLayout);
bottomSheetInternal = d.findViewById(R.id.locUXView);
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetInternal);
bottomSheetBehavior.setHidable(false);
BottomSheetBehavior.from((View)coordinatorLayout.getParent()).setPeekHeight(bottomSheetInternal.getHeight());
bottomSheetBehavior.setPeekHeight(bottomSheetInternal.getHeight());
coordinatorLayout.getParent().requestLayout();
}
});
Utilisation de ce code dans onCreateView.
getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
BottomSheetDialog d = (BottomSheetDialog) dialog;
FrameLayout bottomSheet = (FrameLayout) d.findViewById(R.id.design_bottom_sheet);
CoordinatorLayout coordinatorLayout = (CoordinatorLayout) bottomSheet.getParent();
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setPeekHeight(bottomSheet.getHeight());
coordinatorLayout.getParent().requestLayout();
}
});
J'ai trouvé une autre solution. Peut-être que pour les futurs lecteurs, cela peut être utile.
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
final View root = View.inflate(getContext(), R.layout.fragment_bottom_sheet_choose_time, null);
dialog.setContentView(root);
initView(root);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) ((View) root.getParent()).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
if (behavior != null && behavior instanceof BottomSheetBehavior) {
mBottomSheetBehavior = (BottomSheetBehavior) behavior;
mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback);
root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
root.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int height = root.getMeasuredHeight();
mBottomSheetBehavior.setPeekHeight(height);
}
});
}
}
Comme @Anthonyeef l'a mentionné, ici ViewTreeObserver
vise à obtenir la hauteur de mesure exacte après que la vue est vraiment mesurée et que GlobalOnLayoutListener
est supprimé pour de meilleures performances.
Mais s'il vous plaît, avant de l'utiliser en production, testez cette solution sur différents appareils et écrans, car si votre contenu dans la feuille inférieure est plus élevé que votre écran, il peut produire un comportement de balayage étrange.
Merci @athysirus pour l'approche soignée. Voici la version avec laquelle je me suis retrouvé, au cas où quelqu'un voudrait avoir un échantillon de kotlin fonctionnel.
Il est important de noter que vous devez également supprimer l'écouteur de disposition globale, une fois terminé.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
val bottomSheet = (dialog as BottomSheetDialog).findViewById<View>(com.google.Android.material.R.id.design_bottom_sheet)
BottomSheetBehavior.from<View>(bottomSheet).apply {
state = BottomSheetBehavior.STATE_EXPANDED
peekHeight = 0
}
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})