Con la nueva biblioteca de componentes de material , puede personalizar la forma de su componente usando el shapeAppearanceOverlay
atributo en su estilo ( Nota: requiere la versión 1.1.0 )
Simplemente use el método de BottomSheetDialogFragment
anulación onCreateView
y luego defina su estilo personalizado para los cuadros de diálogo de la hoja inferior.
Defina el bottomSheetDialogTheme
atributo styles.xml
en el tema de su aplicación:
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<item name="colorPrimary">@color/colorPrimary</item>
....
<item name="bottomSheetDialogTheme">@style/CustomBottomSheetDialog</item>
</style>
Entonces simplemente defina su forma favorita 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>
Puede obtener el mismo comportamiento anulando este método en su BottomSheetDialogFragment
(en lugar de agregar el bottomSheetDialogTheme
tema en su aplicación):
@Override public int getTheme() {
return R.style.CustomBottomSheetDialog;
}
En este caso, está utilizando este themeOverlay solo en el single BottomSheetDialogFragment
y no en toda la aplicación.
Nota importante sobre el ESTADO EXPANDIDO :
En el estado expandido, BottomSheet tiene esquinas planas . Puede consultar el comentario oficial en el repositorio de github :
Nuestro equipo de diseño tiene una fuerte opinión de que las esquinas redondeadas indican contenido desplazable, mientras que las esquinas planas indican que no hay contenido adicional. Como tal, no quieren que agreguemos este cambio con fitToContents.
Este comportamiento lo proporciona el BottomSheetBehavior
y es imposible anularlo.
Sin embargo, hay una solución:> DESCARGO DE RESPONSABILIDAD: ¡ puede dejar de funcionar en las próximas versiones!
Puede agregar un BottomSheetCallback
en el 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;
}