Con la nuova libreria Material Component puoi personalizzare la forma del tuo componente utilizzando l' shapeAppearanceOverlay
attributo nel tuo stile ( Nota: richiede la versione 1.1.0 )
Basta usare l' BottomSheetDialogFragment
override del onCreateView
metodo e quindi definire lo stile personalizzato per le finestre di dialogo del foglio inferiore.
Definisci l' bottomSheetDialogTheme
attributo nel styles.xml
tema della tua app:
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<item name="colorPrimary">@color/colorPrimary</item>
....
<item name="bottomSheetDialogTheme">@style/CustomBottomSheetDialog</item>
</style>
Quindi definisci la tua forma preferita con shapeAppearanceOverlay
<style name="CustomBottomSheetDialog" parent="@style/ThemeOverlay.MaterialComponents.BottomSheetDialog">
<item name="bottomSheetStyle">@style/CustomBottomSheet</item>
</style>
<style name="CustomBottomSheet" parent="Widget.MaterialComponents.BottomSheet">
<item name="shapeAppearanceOverlay">@style/CustomShapeAppearanceBottomSheetDialog</item>
</style>
<style name="CustomShapeAppearanceBottomSheetDialog" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSizeTopRight">16dp</item>
<item name="cornerSizeTopLeft">16dp</item>
<item name="cornerSizeBottomRight">0dp</item>
<item name="cornerSizeBottomLeft">0dp</item>
</style>
Puoi ottenere lo stesso comportamento sovrascrivendo questo metodo nel tuo BottomSheetDialogFragment
(invece di aggiungere il bottomSheetDialogTheme
tema della tua app):
@Override public int getTheme() {
return R.style.CustomBottomSheetDialog;
}
In questo caso stai usando questo tema Overlay solo nella singola BottomSheetDialogFragment
e non in tutte le app.
Nota importante sullo STATO ESPANSO :
Nello stato espanso, BottomSheet ha angoli piatti . Puoi controllare il commento ufficiale nel repository github :
Il nostro team di progettazione è fortemente convinto che gli angoli arrotondati indicano contenuto scorrevole mentre gli angoli piatti indicano che non ci sono contenuti aggiuntivi. In quanto tali, non vogliono che aggiungiamo questa modifica con fitToContents.
Questo comportamento è fornito da BottomSheetBehavior
ed è impossibile sovrascriverlo.
Tuttavia c'è una soluzione alternativa -> DISCLAIMER: può smettere di funzionare nelle prossime versioni !!
Puoi aggiungere un BottomSheetCallback
in BottomSheetDialogFragment
:
@NonNull @Override public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
((BottomSheetDialog)dialog).getBehavior().addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override public void onStateChanged(@NonNull View bottomSheet, int newState) {
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
MaterialShapeDrawable newMaterialShapeDrawable = createMaterialShapeDrawable(bottomSheet);
ViewCompat.setBackground(bottomSheet, newMaterialShapeDrawable);
}
}
@Override public void onSlide(@NonNull View bottomSheet, float slideOffset) {
}
});
return dialog;
}
@NotNull private MaterialShapeDrawable createMaterialShapeDrawable(@NonNull View bottomSheet) {
ShapeAppearanceModel shapeAppearanceModel =
ShapeAppearanceModel.builder(getContext(), 0, R.style.CustomShapeAppearanceBottomSheetDialog)
.build();
MaterialShapeDrawable currentMaterialShapeDrawable = (MaterialShapeDrawable) bottomSheet.getBackground();
MaterialShapeDrawable newMaterialShapeDrawable = new MaterialShapeDrawable((shapeAppearanceModel));
newMaterialShapeDrawable.initializeElevationOverlay(getContext());
newMaterialShapeDrawable.setFillColor(currentMaterialShapeDrawable.getFillColor());
newMaterialShapeDrawable.setTintList(currentMaterialShapeDrawable.getTintList());
newMaterialShapeDrawable.setElevation(currentMaterialShapeDrawable.getElevation());
newMaterialShapeDrawable.setStrokeWidth(currentMaterialShapeDrawable.getStrokeWidth());
newMaterialShapeDrawable.setStrokeColor(currentMaterialShapeDrawable.getStrokeColor());
return newMaterialShapeDrawable;
}