为什么我的 BottomSheetDialogFragment 忽略了我的应用程序主题?

Why is my BottomSheetDialogFragment ignoring my app theme?

我刚开始在我的应用程序中使用 BottomSheetDialogFragment,但它似乎忽略了我的应用程序主题。我的应用程序使用深色主题,BottomSheetDialogFragment 以白色背景显示,并且没有使用我的应用程序的强调色。这是唯一一个表现类似的 Android 组件。为什么会这样以及如何解决这个问题?

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;
    }

BottomSheetDialogFragment 的默认主题不是应用程序的主题,而是 Theme.Design.Light.BottomSheetDialog

而那个风格的资源是R.style.Theme_Design_Light_BottomSheetDialog,你可以从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;
  }

因此,您需要更改此设置以使其与应用的主题相匹配。 Here 是 github

上针对此问题提供的几个解决方案

假设您应用的主题是 R.style.AppTheme:

解决方案一:

感谢 Bloody-Badboy

在您的自定义中应用应用的主题 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)
  }

方案二:

感谢 DSteve595

覆盖 BottomSheetDialogFragment 的默认 bottomSheetDialogTheme 样式,如上所述:

<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>

为了进一步研究,this medium 文章也会更清楚