Search code examples
androidandroid-themebottom-sheetbottomsheetdialogfragment

Why is my BottomSheetDialogFragment ignoring my app theme?


I just started using a BottomSheetDialogFragment in my app, however it seems to ignore my app themes. My app uses a dark theme, and the BottomSheetDialogFragment displays with a white background and doesn't use the accent color of my app. This is the only Android component that's behaving like that. Why is that and how to fix this?

public class CustomBottomDialogFragment extends BottomSheetDialogFragment {

    public static CustomBottomDialogFragmentnewInstance(long id) {
        final CustomBottomDialogFragmentdialog = new CustomBottomDialogFragment();
        Bundle args = new Bundle();
        args.putLong(Keys.ARG1, id);
        dialog.setArguments(args);
        return dialog;
    }

  @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        final long id = getArguments().getLong(Keys.ARG1);
        final boolean isLiveStream = PodcastHelper.isLiveStream(podcastId);
        final View view = inflater.inflate(R.layout.custom_bottom_sheet_layout, container, false);

...

        return view;
    }

Solution

  • The default theme of the BottomSheetDialogFragment is not the app's theme, but it's Theme.Design.Light.BottomSheetDialog.

    And the resource of that style them is R.style.Theme_Design_Light_BottomSheetDialog, and you can clearly check this from their class definition

      private static int getThemeResId(@NonNull Context context, int themeId) {
        if (themeId == 0) {
          // If the provided theme is 0, then retrieve the dialogTheme from our theme
          TypedValue outValue = new TypedValue();
          if (context.getTheme().resolveAttribute(R.attr.bottomSheetDialogTheme, outValue, true)) {
            themeId = outValue.resourceId;
          } else {
            // bottomSheetDialogTheme is not provided; we default to our light theme
            themeId = R.style.Theme_Design_Light_BottomSheetDialog;
          }
        }
        return themeId;
      }
    

    So, you need to change this to be matched with the app's theme. Here are couple of solutions that are provided for this issue on github

    Assuming your app's theme is R.style.AppTheme:

    Solution 1:

    Credits to Bloody-Badboy

    Apply the app's theme within your custom BottomSheetDialogFragment:

     override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
      ): View? {
        val contextThemeWrapper = ContextThemeWrapper(activity, R.style.AppTheme) // your app theme here
        return inflater.cloneInContext(contextThemeWrapper).inflate(R.layout.custom_bottom_sheet_layout, container, false)
      }
    

    Solution 2:

    Credits to DSteve595

    Override the the default bottomSheetDialogTheme style of the BottomSheetDialogFragment as mentioned above:

    <style name="AppTheme" parent=".....">
        <item name="bottomSheetDialogTheme">@style/ThemeOverlay.YourApp.BottomSheetDialog</item>
    </style>
    
    <style name="ThemeOverlay.YourApp.BottomSheetDialog" parent="ThemeOverlay.MaterialComponents.Dialog">
      <item name="android:windowBackground">@android:color/transparent</item>
      <item name="android:windowAnimationStyle">@style/Animation.MaterialComponents.BottomSheetDialog</item>
      <item name="bottomSheetStyle">@style/Widget.MaterialComponents.BottomSheet.Modal</item>
    </style>
    

    For further research, this medium article also would make it more clear