Dzięki nowej bibliotece komponentów materiałowych możesz dostosować kształt komponentu za pomocą shapeAppearanceOverlay
atrybutu w swoim stylu ( uwaga: wymaga wersji 1.1.0 )
Po prostu użyj BottomSheetDialogFragment
nadpisywania onCreateView
metody, a następnie zdefiniuj własny styl dla okien dialogowych dolnego arkusza.
Zdefiniuj bottomSheetDialogTheme
atrybut w styles.xml
motywie aplikacji:
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<item name="colorPrimary">@color/colorPrimary</item>
....
<item name="bottomSheetDialogTheme">@style/CustomBottomSheetDialog</item>
</style>
Następnie po prostu zdefiniuj swój ulubiony kształt za pomocą 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>
Możesz uzyskać to samo zachowanie, zastępując tę metodę w swoim BottomSheetDialogFragment
(zamiast dodawać bottomSheetDialogTheme
w motywie aplikacji):
@Override public int getTheme() {
return R.style.CustomBottomSheetDialog;
}
W tym przypadku używasz tego motywu Nakładaj tylko w pojedynczej aplikacji, BottomSheetDialogFragment
a nie w całej aplikacji.
Ważna uwaga na temat STANU ROZSZERZONEGO :
W stanie rozwiniętym BottomSheet ma płaskie rogi . Możesz sprawdzić oficjalny komentarz w repozytorium github :
Nasz zespół projektantów jest głęboko przekonany, że zaokrąglone rogi wskazują zawartość przewijalną, a płaskie rogi wskazują, że nie ma dodatkowej zawartości. W związku z tym nie chcą, abyśmy dodawali tę zmianę za pomocą fitToContents.
To zachowanie jest zapewniane przez BottomSheetBehavior
i nie można go zastąpić.
Istnieje jednak obejście -> ZRZECZENIE SIĘ: może przestać działać w następnych wersjach !!
Możesz dodać BottomSheetCallback
w 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;
}