datetimepicker icon indicating copy to clipboard operation
datetimepicker copied to clipboard

design: 'material' causes app to crash

Open nick-michael opened this issue 7 months ago • 7 comments

Bug report

Summary

Setting the design property to material causes the app to crash upon opening the date picker. Using Expo v53, datetimepicker v8.4.1 Included the @react-native-community/datetimepicker plugin both with no config and with some basic theming which works for the default picker. Running on an Expo development build.

Crash details:

java.lang.IllegalArgumentException: com.google.android.material.datepicker.MaterialDatePicker requires a value for the {bundle-identifier}:attr/materialCalendarTheme attribute to be set in your app theme. You can either set the attribute in your theme or update your theme to inherit from Theme.MaterialComponents (or a descendant).
  com.google.android.material.resources.MaterialAttributes.resolveTypedValueOrThrow(MaterialAttributes.java:72)
  com.google.android.material.resources.MaterialAttributes.resolveOrThrow(MaterialAttributes.java:89)
  com.google.android.material.datepicker.SingleDateSelector.getDefaultThemeResId(SingleDateSelector.java:162)
  com.google.android.material.datepicker.MaterialDatePicker.getThemeResId(MaterialDatePicker.java:266)
  com.google.android.material.datepicker.MaterialDatePicker.onCreateDialog(MaterialDatePicker.java:272)
  androidx.fragment.app.DialogFragment.prepareDialog(DialogFragment.java:930)
  androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:844)
  androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1755)
  androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:527)
  androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:272)
  androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1943)
  androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1845)
  androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1782)
  androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:565)
  android.os.Handler.handleCallback(Handler.java:995)
  android.os.Handler.dispatchMessage(Handler.java:103)
  android.os.Looper.loopOnce(Looper.java:248)
  android.os.Looper.loop(Looper.java:338)
  android.app.ActivityThread.main(ActivityThread.java:9067)
  java.lang.reflect.Method.invoke(Native Method)
  com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932)

Reproducible sample code

DateTimePickerAndroid.open({ value: dateToRender, onChange: handleDateChange, mode: 'date', design: 'material' });

Steps to reproduce

  1. Create an Expo dev build with an app that's using the datepicker library

  2. Set the datepicker to open programmatically, using DateTimePickerAndroid.open and provide the design: 'material' option

  3. Launch the app and open the datepicker

  4. npx react-native info output:

    info Fetching system and libraries information...
    System:
      OS: Windows 10 10.0.19045
      CPU: "(16) x64 AMD Ryzen 7 5800X 8-Core Processor             "
      Memory: 7.36 GB / 31.93 GB
    Binaries:
      Node:
        version: 24.1.0
        path: C:\nvm4w\nodejs\node.EXE
      Yarn: Not Found
      npm:
        version: 11.3.0
        path: C:\nvm4w\nodejs\npm.CMD
      Watchman: Not Found
    SDKs:
      Android SDK: Not Found
      Windows SDK: Not Found
    IDEs:
      Android Studio: Not Found
      Visual Studio: Not Found
    Languages:
      Java: Not Found
      Ruby: Not Found
    npmPackages:
      "@react-native-community/cli":
        installed: 18.0.0
        wanted: latest
      react:
        installed: 19.0.0
        wanted: 19.0.0
      react-native:
        installed: 0.79.3
        wanted: 0.79.3
      react-native-windows: Not Found
    npmGlobalPackages:
      "*react-native*": Not Found
    Android:
      hermesEnabled: Not found
      newArchEnabled: Not found
    iOS:
      hermesEnabled: Not found
      newArchEnabled: Not found
    

    Time zone name (If the problem you have is related to unexpected time / date. See list in https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).

nick-michael avatar Jun 14 '25 19:06 nick-michael

Bug report

Summary

Setting the design property to material causes the app to crash upon opening the date picker. Using Expo v53, datetimepicker v8.4.1 Included the @react-native-community/datetimepicker plugin both with no config and with some basic theming which works for the default picker. Running on an Expo development build.

Crash details:

java.lang.IllegalArgumentException: com.google.android.material.datepicker.MaterialDatePicker requires a value for the {bundle-identifier}:attr/materialCalendarTheme attribute to be set in your app theme. You can either set the attribute in your theme or update your theme to inherit from Theme.MaterialComponents (or a descendant).
  com.google.android.material.resources.MaterialAttributes.resolveTypedValueOrThrow(MaterialAttributes.java:72)
  com.google.android.material.resources.MaterialAttributes.resolveOrThrow(MaterialAttributes.java:89)
  com.google.android.material.datepicker.SingleDateSelector.getDefaultThemeResId(SingleDateSelector.java:162)
  com.google.android.material.datepicker.MaterialDatePicker.getThemeResId(MaterialDatePicker.java:266)
  com.google.android.material.datepicker.MaterialDatePicker.onCreateDialog(MaterialDatePicker.java:272)
  androidx.fragment.app.DialogFragment.prepareDialog(DialogFragment.java:930)
  androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:844)
  androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1755)
  androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:527)
  androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:272)
  androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1943)
  androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1845)
  androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1782)
  androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:565)
  android.os.Handler.handleCallback(Handler.java:995)
  android.os.Handler.dispatchMessage(Handler.java:103)
  android.os.Looper.loopOnce(Looper.java:248)
  android.os.Looper.loop(Looper.java:338)
  android.app.ActivityThread.main(ActivityThread.java:9067)
  java.lang.reflect.Method.invoke(Native Method)
  com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932)

Reproducible sample code

DateTimePickerAndroid.open({ value: dateToRender, onChange: handleDateChange, mode: 'date', design: 'material' });

Steps to reproduce

  1. Create an Expo dev build with an app that's using the datepicker library

  2. Set the datepicker to open programmatically, using DateTimePickerAndroid.open and provide the design: 'material' option

  3. Launch the app and open the datepicker

  4. npx react-native info output: info Fetching system and libraries information... System: OS: Windows 10 10.0.19045 CPU: "(16) x64 AMD Ryzen 7 5800X 8-Core Processor " Memory: 7.36 GB / 31.93 GB Binaries: Node: version: 24.1.0 path: C:\nvm4w\nodejs\node.EXE Yarn: Not Found npm: version: 11.3.0 path: C:\nvm4w\nodejs\npm.CMD Watchman: Not Found SDKs: Android SDK: Not Found Windows SDK: Not Found IDEs: Android Studio: Not Found Visual Studio: Not Found Languages: Java: Not Found Ruby: Not Found npmPackages: "@react-native-community/cli": installed: 18.0.0 wanted: latest react: installed: 19.0.0 wanted: 19.0.0 react-native: installed: 0.79.3 wanted: 0.79.3 react-native-windows: Not Found npmGlobalPackages: "react-native": Not Found Android: hermesEnabled: Not found newArchEnabled: Not found iOS: hermesEnabled: Not found newArchEnabled: Not found

    Time zone name (If the problem you have is related to unexpected time / date. See list in https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).

I encountered the same issue and was able to fix it by adjusting the native Android theme configuration.

✅ Solution

  1. Run expo prebuild This generates the native project files needed for customization:

    npx expo prebuild
    

    ⚠️ Note: If you use the --clean flag, be aware it will remove any changes you've made to native files.

  2. Update the Android theme Open android/app/src/main/res/values/styles.xml and change the parent of the AppTheme style to use Material3. Also, define the required materialCalendarTheme and materialTimePickerTheme.

    🛠 Example change:

    <resources xmlns:tools="http://schemas.android.com/tools">
    -  <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    +  <style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar">
        <!-- Your custom AppTheme items -->
    +    <item name="materialCalendarTheme">@style/ThemeOverlay.App.DatePicker</item>
    +    <item name="materialTimePickerTheme">@style/ThemeOverlay.App.TimePicker</item>
      </style>
      <!-- Your custom styles -->
    +  <style name="ThemeOverlay.App.DatePicker" parent="ThemeOverlay.Material3.MaterialCalendar"/>
    +  <style name="ThemeOverlay.App.TimePicker" parent="ThemeOverlay.Material3.MaterialTimePicker"/>
    </resources>
    
  3. Working styles.xml example:

    <resources xmlns:tools="http://schemas.android.com/tools">
      <style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar">
        <item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="android:statusBarColor">#0C5580</item>
        <item name="materialCalendarTheme">@style/ThemeOverlay.App.DatePicker</item>
        <item name="materialTimePickerTheme">@style/ThemeOverlay.App.TimePicker</item>
        <item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>
      </style>
    
      <style name="ThemeOverlay.App.DatePicker" parent="ThemeOverlay.Material3.MaterialCalendar"/>
      <style name="ThemeOverlay.App.TimePicker" parent="ThemeOverlay.Material3.MaterialTimePicker"/>
    
      <style name="Theme.App.SplashScreen" parent="Theme.SplashScreen">
        <item name="windowSplashScreenBackground">@color/splashscreen_background</item>
        <item name="windowSplashScreenAnimatedIcon">@drawable/splashscreen_logo</item>
        <item name="postSplashScreenTheme">@style/AppTheme</item>
      </style>
    </resources>
    

After making these changes, the design: 'material' option works as expected without crashing the app.

GeisonJr avatar Jun 30 '25 14:06 GeisonJr

This is unfortunately not an option if you are using Expo pipeline to build the android bundle

nick-michael avatar Jul 09 '25 18:07 nick-michael

you can create custom plugin to modify android styles when running prebuild

// ./plugins/my-custom-styles.js
const { withAndroidStyles } = require("@expo/config-plugins");

const withCustomStyles = (config) => {
  return withAndroidStyles(config, async (config) => {
    config.modResults = applyCustomStyles(config.modResults);
    return config;
  });
};

function applyCustomStyles(styles) {
  // Add items to the App Theme
  const appTheme = styles.resources.style.find(
    (style) => style.$.name === "AppTheme",
  );
  if (appTheme) {
    appTheme.$.parent = "Theme.Material3.DayNight.NoActionBar"; // or "Theme.EdgeToEdge.Material3"
    appTheme.item.push({
      _: "@style/AppCalendar",
      $: { name: "materialCalendarTheme" },
    });
  }

  // Add new style definition
  styles.resources.style.push({
    $: {
      name: "AppCalendar",
      parent: "ThemeOverlay.Material3.MaterialCalendar",
    },
    item: [
      { _: "@color/colorPrimary", $: { name: "colorPrimary" } },
      { _: "@style/AppCalendarStyle", $: { name: "materialCalendarStyle" } },
    ],
  });

  styles.resources.style.push({
    $: {
      name: "AppCalendarStyle",
      parent: "@style/Widget.Material3.MaterialCalendar",
    },
    item: [{ _: "@color/background_color", $: { name: "backgroundTint" } }],
  });

  return styles;
}

module.exports = withCustomStyles;

then define this file in your app.json to run when using expo prebuild

{
  "expo": {
    ...
    "plugins": [
      "./plugins/my-custom-styles.js",
      ...
    ],
    ...
  }
}

run npx expo prebuild --clean -p android

julian-dueck avatar Jul 14 '25 12:07 julian-dueck

👋 If you need dynamic styles (styles that are passed through javascript) you could use https://github.com/s77rt/react-native-date-picker

Disclaimer: I'm the author of that library

s77rt avatar Jul 28 '25 00:07 s77rt

I have the same issue.

eNiiju avatar Aug 23 '25 15:08 eNiiju

Same issue with react-native-cli. what could be the permanent solution ???

vaibhavchvn86 avatar Sep 08 '25 05:09 vaibhavchvn86

@GeisonJr will your solution impact the devices which does not support material theme. AFAIK AppCompat is available from api v7+ and Material is available from v21+

Kushagra-ag avatar Nov 05 '25 06:11 Kushagra-ag