I\'m using really naive code to show a bottom sheet dialog fragment:
class LogoutBottomSheetFragment : BottomSheetDialogFragment() {
override fun onCrea
BottomSheetDialogFragment
extends DialogFragment
. Inside BottomSheetDialog it's creating a Dialog inside onCreateDialog
public class BottomSheetDialogFragment extends AppCompatDialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new BottomSheetDialog(getContext(), getTheme());
}
}
The dim layer is a property of dialog which is applying to whole window. Then only it will cover the status bar. If you need dim layer without bottom buttons, then you have to do manually by showing a layer inside layout and changing status bar colour accordingly.
Apply theme for dialogfragment as given below
class LogoutBottomSheetFragment : BottomSheetDialogFragment() {
init {
setStyle(DialogFragment.STYLE_NORMAL,R.style.dialog);
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.view_image_source_chooser, container, false)
return view
}
}
With styles as
<style name="dialog" parent="Base.Theme.AppCompat.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
I had the same problem. After looking into sources I found a workaround (a little bit hacky, but I found no alternatives).
public class YourDialog extends BottomSheetDialogFragment {
//your code
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new FitSystemWindowsBottomSheetDialog(getContext());
}
}
public class FitSystemWindowsBottomSheetDialog extends BottomSheetDialog {
public FitSystemWindowsBottomSheetDialog(Context context) {
super(context);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getWindow() != null && Build.VERSION.SDK_INT >= 21) {
findViewById(android.support.design.R.id.coordinator).setFitsSystemWindows(false);
findViewById(android.support.design.R.id.container).setFitsSystemWindows(false);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS |
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
}
}
And, finally, don't forget to add android:fitsSystemWindows="true" at the root of your dialog layout.
Hope it helps.
I know there is many solutions here already but all of them seems too much to me, so I found this very simple solution here, credit goes to Arthur Nagy:
just override the getTheme method in the BottomSheetDialogFragment:
override fun getTheme(): Int = R.style.Theme_NoWiredStrapInNavigationBar
and in styles.xml:
<style name="Theme.NoWiredStrapInNavigationBar" parent="@style/Theme.Design.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:navigationBarColor">@color/bottom_sheet_bg</item>
<item name="android:statusBarColor">@android:color/transparent</item>
</style>
You can also add support for night mode by changing the color @color/bottom_sheet_bg
in the values-night
assets folder
There is a way to avoid changes in Java/Kotlin code, the issue can be fully resolved in XML nowadays:
<style name="MyTheme" parent="Theme.MaterialComponents">
<item name="bottomSheetDialogTheme">@style/BottomSheet</item>
</style>
<style name="BottomSheet" parent="Theme.MaterialComponents.Light.BottomSheetDialog">
<item name="android:windowIsFloating">false</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">?android:colorBackground</item>
<item name="android:navigationBarDividerColor">?android:colorBackground</item>
</style>
I also had an issue with my theme/style not being applied to the views inside BottomSheetDialogFragment
, here's what I did to fix that in my base BottomSheetDialogFragment
:
override fun onGetLayoutInflater(savedInstanceState: Bundle?): LayoutInflater {
val inflater = super.onGetLayoutInflater(savedInstanceState)
val wrappedContext = ContextThemeWrapper(requireContext(), R.style.My_Theme)
return inflater.cloneInContext(wrappedContext)
}
Don't use BottomSheetDialogFragment
.I would prefer use adding bottom sheet by wrapping the layout in the coordinator layout and attaching BottomSheetBehaiviour to that layout
You can follow this as an example
Use follow API to setContentView instead of overriding onCreateView.
val dialog = BottomSheetDialog(context)
dialog.setContentView(R.layout.your_layout)
BottomSheetDialog.setContentView will setup the correct behavior for BottomSheetDialog. You can see the source code:
public void setContentView(@LayoutRes int layoutResId) {
super.setContentView(this.wrapInBottomSheet(layoutResId, (View)null, (LayoutParams)null));
}
private View wrapInBottomSheet(int layoutResId, View view, LayoutParams params) {
FrameLayout container = (FrameLayout)View.inflate(this.getContext(), layout.design_bottom_sheet_dialog, (ViewGroup)null);
CoordinatorLayout coordinator = (CoordinatorLayout)container.findViewById(id.coordinator);
if (layoutResId != 0 && view == null) {
view = this.getLayoutInflater().inflate(layoutResId, coordinator, false);
}
// ... more stuff
}