Com a nova biblioteca de componentes de materiais, você pode personalizar a forma de seu componente usando o shapeAppearanceOverlay
atributo em seu estilo ( Nota: requer a versão 1.1.0 )
Basta usar a BottomSheetDialogFragment
substituição do onCreateView
método e definir seu estilo personalizado para Diálogos de Folha Inferior.
Defina o bottomSheetDialogTheme
atributo no styles.xml
tema do seu aplicativo:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
....
<item name="bottomSheetDialogTheme">@style/CustomBottomSheetDialog</item>
</style>
Em seguida, basta definir sua forma favorita com 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>
Você pode obter o mesmo comportamento substituindo este método no seu BottomSheetDialogFragment
(em vez de adicionar o bottomSheetDialogTheme
no tema do seu aplicativo):
@Override public int getTheme() {
return R.style.CustomBottomSheetDialog;
}
Nesse caso, você está usando este themeOverlay apenas no único BottomSheetDialogFragment
e não em todos os aplicativos.
Nota importante sobre o ESTADO EXPANDIDO :
No estado expandido, BottomSheet tem cantos planos . Você pode verificar o comentário oficial no repo do github :
Nossa equipe de design tem uma forte opinião de que cantos arredondados indicam conteúdo rolável, enquanto cantos planos indicam que não há conteúdo adicional. Como tal, eles não querem que adicionemos essa alteração com fitToContents.
Este comportamento é fornecido pelo BottomSheetBehavior
e é impossível substituí-lo.
No entanto, há uma solução alternativa -> AVISO LEGAL: pode parar de funcionar nas próximas versões !!
Você pode adicionar um BottomSheetCallback
no 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) {
//In the EXPANDED STATE apply a new MaterialShapeDrawable with rounded cornes
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 =
//Create a ShapeAppearanceModel with the same shapeAppearanceOverlay used in the style
ShapeAppearanceModel.builder(getContext(), 0, R.style.CustomShapeAppearanceBottomSheetDialog)
.build();
//Create a new MaterialShapeDrawable (you can't use the original MaterialShapeDrawable in the BottoSheet)
MaterialShapeDrawable currentMaterialShapeDrawable = (MaterialShapeDrawable) bottomSheet.getBackground();
MaterialShapeDrawable newMaterialShapeDrawable = new MaterialShapeDrawable((shapeAppearanceModel));
//Copy the attributes in the new MaterialShapeDrawable
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;
}