【问题标题】:How to customize a date picker如何自定义日期选择器
【发布时间】:2018-05-13 22:36:15
【问题描述】:

我正在使用 showDatePicker() 方法在我的 Flutter 应用程序中显示日期选择器。如何自定义日期选择器的颜色?

这是我的主题代码:

class CustomTheme extends Theme {
  /*
   * Colors:
   *    Primary Blue: #335C81 (51, 92, 129)
   *    Light Blue:   #74B3CE (116, 179, 206)
   *    Yellow:       #FCA311 (252, 163, 17)
   *    Red:          #E15554 (255, 85, 84)
   *    Green:        #3BB273 (59, 178, 115)
   */

  static int _fullAlpha = 255;
  static Color blueDark =  new Color.fromARGB(_fullAlpha, 51, 92, 129);
  static Color blueLight = new Color.fromARGB(_fullAlpha, 116, 179, 206);
  static Color yellow =    new Color.fromARGB(_fullAlpha, 252, 163, 17);
  static Color red =       new Color.fromARGB(_fullAlpha, 255, 85, 84);
  static Color green =     new Color.fromARGB(_fullAlpha, 59, 178, 115);

  static Color activeIconColor = yellow;


  CustomTheme(Widget child): super(
    child: child,
    data: new ThemeData(
      primaryColor: blueDark,
      accentColor: yellow,
      cardColor: blueLight,
      backgroundColor: blueDark,
      highlightColor: red,
      splashColor: green
    )
  );
}

这是我在主题中包装页面的代码:

  @override
  Widget build(BuildContext context) {
    [...]
    return new CustomTheme(
      new Scaffold(
        [...]
      )
    );
  }

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    颤振 2.0.2

        showDatePicker(
          builder: (context, child) {
            return Theme(
              data: Theme.of(context).copyWith(
                colorScheme: ColorScheme.light(
                  primary: Colors.yellow, // header background color
                  onPrimary: Colors.black, // header text color
                  onSurface: Colors.green, // body text color
                ),
                textButtonTheme: TextButtonThemeData(
                  style: TextButton.styleFrom(
                    primary: Colors.red, // button text color
                  ),
                ),
              ),
              child: child!,
            );
          },
        );
      },
    );
    

    【讨论】:

    • 也为Theme.of(context) 大喊大叫,而不是仅仅为其中一个主题编码。谢谢!
    • 天的大小如何(绿色文字)?我怎样才能改变这些?
    • 太棒了!正是我需要的 TextButton 颜色。谢谢!
    【解决方案2】:

    除了确定/取消按钮之外,上述答案都有效。只需添加这个,以防有人需要帮助定制它。它是 colorScheme 和 buttonTheme 的组合。

    showTimePicker(
      context: context,
      initialTime: TimeOfDay(hour: hour, minute: minute),
      builder: (BuildContext context, Widget child) {
        return Theme(
          data: ThemeData.light().copyWith(
              primaryColor: const Color(0xFF8CE7F1),
              accentColor: const Color(0xFF8CE7F1),
              colorScheme: ColorScheme.light(primary: const Color(0xFF8CE7F1)),
              buttonTheme: ButtonThemeData(
                textTheme: ButtonTextTheme.primary
              ),
          ),
          child: child,
        );
      },
    );
    

    【讨论】:

      【解决方案3】:

      试试这个

      showDatePicker(
                context: context,
                initialDate: DateTime.now(),
                firstDate: DateTime(1970),
                builder: (BuildContext context, Widget child) {
                  return Theme(
                    data: ThemeData.dark().copyWith(
                      colorScheme: ColorScheme.dark(
                          primary: Colors.deepPurple,
                          onPrimary: Colors.white,
                          surface: Colors.pink,
                          onSurface: Colors.yellow,
                          ),
                      dialogBackgroundColor:Colors.blue[900],
                    ),
                    child: child,
                  );
                },
              );
      

      【讨论】:

        【解决方案4】:

        只需在 main.dart 中添加 colorScheme: ColorScheme.light(primary: const Color(0xFFed1e25)),
        它的控件 showDatePicker 标题颜色

        theme: ThemeData()

        runApp(
            MaterialApp(
              routes: <String, WidgetBuilder>{
                '/': (BuildContext context) => Home(),
              },
              debugShowCheckedModeBanner: false,
              title: 'Hello',
              theme: ThemeData(
                ...
                // CUSTOMIZE showDatePicker Colors
                colorScheme: ColorScheme.light(primary: const Color(0xFFed1e25)),
                buttonTheme: ButtonThemeData(textTheme: ButtonTextTheme.primary),
                //
                ...
              ),
        

        【讨论】:

          【解决方案5】:

          showDatePicker() 方法提供了 builder 参数。

          试试这个:

          const MaterialColor buttonTextColor = const MaterialColor(
            0xFF4A5BF6,
            const <int, Color>{
              50: const Color(0xFF4A5BF6),
              100: const Color(0xFF4A5BF6),
              200: const Color(0xFF4A5BF6),
              300: const Color(0xFF4A5BF6),
              400: const Color(0xFF4A5BF6),
              500: const Color(0xFF4A5BF6),
              600: const Color(0xFF4A5BF6),
              700: const Color(0xFF4A5BF6),
              800: const Color(0xFF4A5BF6),
              900: const Color(0xFF4A5BF6),
            },
          );
          
          showDatePicker(
            context: context,
            initialDate: DateTime.now(),
            firstDate: DateTime(2018),
            lastDate: DateTime(2030),
            builder: (BuildContext context, Widget child) {
              return Theme(
                  data: ThemeData.light().copyWith(
                    primarySwatch: buttonTextColor,//OK/Cancel button text color
                    primaryColor: const Color(0xFF4A5BF6),//Head background
                    accentColor: const Color(0xFF4A5BF6)//selection color
                    //dialogBackgroundColor: Colors.white,//Background color
                     ),     
                    child: child,
              );
            },
          );
          

          你会得到这样的东西:

          【讨论】:

          • 我还想补充一点,如果你想改变OK/CANCEL按钮文字颜色,可以使用primarySwatch
          • @SinanBaymammadli 谢谢,我的回答已根据您的建议进行了更新。
          【解决方案6】:

          我假设您希望从您的主题中以不同方式自定义日期选择器。通常,日期选择器会遵循您的主题。

          如果是这样,将触发操作的按钮包装在 Builder 中的 Theme 中。例如,这是一个弹出橙色日期选择器的 FAB(在轻材质应用程序主题中),继承了主主题的其余部分。

            floatingActionButton: new Theme(
              data: Theme.of(context).copyWith(
                    primaryColor: Colors.amber,
                  ),
              child: new Builder(
                builder: (context) => new FloatingActionButton(
                      child: new Icon(Icons.date_range),
                      onPressed: () => showDatePicker(
                            context: context,
                            initialDate: new DateTime.now(),
                            firstDate:
                                new DateTime.now().subtract(new Duration(days: 30)),
                            lastDate: new DateTime.now().add(new Duration(days: 30)),
                          ),
                    ),
              ),
            ),
          

          查看 date_picker.dart 的源代码,了解 Theme 的哪些部分影响日期选择器的不同方面。

          如果您只想让选择器跟随主题,这里有一个工作示例

          import 'package:flutter/material.dart';
          
          class PickerThemeDemo extends StatelessWidget {
            @override
            Widget build(BuildContext context) {
              return new Scaffold(
                appBar: new AppBar(title: const Text('Picker theme demo')),
                body: new Container(),
                floatingActionButton: new FloatingActionButton(
                  child: new Icon(Icons.date_range),
                  onPressed: () => showDatePicker(
                        context: context,
                        initialDate: new DateTime.now(),
                        firstDate: new DateTime.now().subtract(new Duration(days: 30)),
                        lastDate: new DateTime.now().add(new Duration(days: 30)),
                      ),
                ),
              );
            }
          }
          
          Color hexToColor(int rgb) => new Color(0xFF000000 + rgb);
          
          class CustomTheme extends Theme {
            //Primary Blue: #335C81 (51, 92, 129)
            //Light Blue:   #74B3CE (116, 179, 206)
            //Yellow:       #FCA311 (252, 163, 17)
            //Red:          #E15554 (255, 85, 84)
            //Green:        #3BB273 (59, 178, 115)
          
            static Color blueDark = hexToColor(0x335C81);
            static Color blueLight = hexToColor(0x74B3CE);
            static Color yellow = hexToColor(0xFCA311);
            static Color red = hexToColor(0xE15554);
            static Color green = hexToColor(0x3BB273);
          
            CustomTheme(Widget child)
                : super(
                    child: child,
                    data: new ThemeData(
                      primaryColor: blueDark,
                      accentColor: yellow,
                      cardColor: blueLight,
                      backgroundColor: blueDark,
                      highlightColor: red,
                      splashColor: green,
                    ),
                  );
          }
          
          void main() {
            runApp(
              new MaterialApp(
                home: new CustomTheme(new PickerThemeDemo()),
              ),
            );
          }
          

          如果您想将主题应用到整个应用程序,可以将其最简洁(无需 CustomTheme 类)添加到 Material 应用程序:

          Color hexToColor(int rgb) => new Color(0xFF000000 + rgb);
          
          void main() {
            runApp(
              new MaterialApp(
                theme: new ThemeData(
                  brightness: Brightness.light,
                  primaryColor: hexToColor(0x335C81),
                  accentColor: hexToColor(0xFCA311),
                  splashColor: hexToColor(0x3BB273),
                ),
                home: new PickerThemeDemo(),
              ),
            );
          } 
          

          【讨论】:

          • 我希望日期选择器遵循我自定义的主题。整个页面都包含在主题中,但由于某种原因它没有滚动到日期选择器。
          • 这对我有用。我在可怕的背景上有斜体文字,在 OK 和 Cancel 上有生动的飞溅。什么不适合你?
          • 我将整个页面包装在自定义主题中,我在其中设置了原色。当用户点击ListTile 时会显示日期选择器。我会用我的主题代码更新问题。
          • 如果我将我的应用程序包装在您的自定义主题中,我的日期选择器有:深蓝色横幅、今天的日期、选定的日期、黄色的确定和取消,单击时确定和取消显示绿色。这和你看到的不一样吗?
          • 查看编辑后的答案,或者在您的 Scaffold 上方插入一个 Builder,如下所示: Widget build(BuildContext context) { return new CustomTheme( new Builder( builder: (context) => new Scaffold(跨度>
          【解决方案7】:

          当我在玩 showDatePicker 主题数据时,我发现了以下内容:

          final DateTime now = DateTime.now();
          
          final DateTime? selectedDate = await showDatePicker(
              context: context,
              initialDate: now,
              firstDate: DateTime(now.year, now.month, now.day),
              lastDate: DateTime(now.year + 2),
              builder: (context, child) {
                return Theme(
                  data: ThemeData.dark().copyWith(
                      colorScheme: const ColorScheme.dark(
                          onPrimary: Colors.black, // selected text color
                          onSurface: Colors.amberAccent, // default text color
                          primary: Colors.amberAccent // circle color
                          ),
                      dialogBackgroundColor: Colors.black54,
                      textButtonTheme: TextButtonThemeData(
                          style: TextButton.styleFrom(
                              textStyle: const TextStyle(
                                  color: Colors.amber,
                                  fontWeight: FontWeight.normal,
                                  fontSize: 12,
                                  fontFamily: 'Quicksand'),
                              primary: Colors.amber, // color of button's letters
                              backgroundColor: Colors.black54, // Background color
                              shape: RoundedRectangleBorder(
                                  side: const BorderSide(
                                      color: Colors.transparent,
                                      width: 1,
                                      style: BorderStyle.solid),
                                  borderRadius: BorderRadius.circular(50))))),
                  child: child!,
                );
              });
          

          【讨论】:

            【解决方案8】:

            2021 年更新

            颤振 2.5.3

            showDatePicker(
                      context: context,
                      builder: (context, child) {
                        return Theme(
                          data: Theme.of(context).copyWith(
                            colorScheme: ColorScheme.light(
                              primary: Colors.blue,
                              onPrimary: Colors.white,
                              onSurface: Colors.black,
                            ),
                            textButtonTheme: TextButtonThemeData(
                              style: TextButton.styleFrom(
                                primary: Colors.white,
                                backgroundColor: Colors.blue,
                                textStyle: TextStyle(
                                  fontSize: 16,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                          child: child!,
                        );
                      },
                      helpText: 'Select Date',
                      initialDate: _selectedDate,
                      firstDate: DateTime.now(),
                      lastDate: DateTime.now().add(Duration(days: 14)),
                    ).then((pickedDate) {
                      if (pickedDate == null) {
                        return;
                      }
                      setState(() {
                        _selectedDate = pickedDate;
                        _date.value = TextEditingValue(
                            text: DateFormat('dd-MM-yyyy').format(_selectedDate));
                      });
                    });
            

            【讨论】:

            • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
            【解决方案9】:
            **You can try this solution. I sloved my problem apply to this solution**
            
            Future<DateTime> selectDate() async {
            return await showDatePicker(
              context: context,
              initialDatePickerMode: DatePickerMode.day,
              initialDate: selecteDate,
              builder: (BuildContext context, Widget child) {
                return Theme(
                  data: ThemeData.light().copyWith(
                      primaryColor: Colors.teal,
                      accentColor: Colors.teal,
                      colorScheme: ColorScheme.light(primary: Colors.teal),
                      buttonTheme: ButtonThemeData(
                        textTheme: ButtonTextTheme.primary
                      ),
                  ),
                  child: child,
                );
              },
              firstDate: widget.initialDate ?? DateTime.now().subtract(Duration(days: 
              30)),
              lastDate: widget.lastDate ?? DateTime.now().add(Duration(days: 30)),
             );
            }
            

            【讨论】:

              【解决方案10】:

              如果您只想更改 datePicker 的主题数据,则需要将负责显示 datePicker 的小部件包装在 Builder 小部件中,并最终将其全部包装在 Theme 小部件中,如下所示:

              PS:但是在我写这个答案的时候,文本颜色(“OK/CANCEL”)没有被接受。这是flutter框架中的一个问题。 19623 是问题所在。

              Widget dateOfBirth(String hintText){
              
                  return Theme(
                    data: Theme.of(context).copyWith(
                      primaryColor: Color(0xFFFF3661), //color of the main banner
                      accentColor: Color(0xFFFF3661), //color of circle indicating the selected date
                      buttonTheme: ButtonThemeData(
                        textTheme: ButtonTextTheme.accent //color of the text in the button "OK/CANCEL"
                      ),
                    ),
                    child: Builder(              // This widget is required for the theme to be applied
                      builder: (context){
                        return GestureDetector(
                          onTap: () async {
              
                            DateTime initialDate = DateTime(DateTime.now().year - 17,DateTime.now().month,DateTime.now().day);
              
                            final picked = await showDatePicker(
                              context: context,
                              initialDate: initialDate,
                              firstDate: DateTime(DateTime.now().year - 100,DateTime.now().month,DateTime.now().day),
                              lastDate: DateTime(DateTime.now().year - 17,DateTime.now().month,DateTime.now().day),
                            );
              
                            if(picked != null && picked != dobSelected){
                              setState(() {
                                dobSelected = picked; // dobSelected is variable to store the selected value
                              });
                            }
              
                            return picked;
                          },
                          child: Padding(        //You can use any other widget here
                            padding: const EdgeInsets.symmetric(horizontal: 40.0),
                            child: Container(
                                height: 55,
                                width: MediaQuery.of(context).size.width,
                                alignment: Alignment.centerLeft,
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.all(Radius.circular(3)),
                                  color: Color(0xFFF2F2F2),
                                ),
                                padding: const EdgeInsets.symmetric(horizontal: 13),
                                child: dobSelected == null?Text('Date Of Birth',style: TextStyle(color: widget.isLender?Color(0xFF8B8B8B):Color(0xFFB3B1B1),fontSize: 15),):Text(DateFormat('yyyy-MM-dd').format(dobSelected))
                            ),
                          ),
                        );
                      },
                    ),
                  );
                }
              

              输出

              希望对你有帮助!!!

              【讨论】:

                【解决方案11】:

                如果您在 2021 年更改颜色时仍然面临零安全问题..那么这里是简单的解决方案

                 Future<void> _selectDate(BuildContext context) async {
                DateTime? picked = await showDatePicker(
                      context: context,
                    builder: (BuildContext context, Widget ?child) {
                      return Theme(
                        data: ThemeData(
                          primarySwatch: Colors.grey,
                          splashColor: Colors.black,
                          textTheme: TextTheme(
                            subtitle1: TextStyle(color: Colors.black),
                            button: TextStyle(color: Colors.black),
                          ),
                          accentColor: Colors.black,
                          colorScheme: ColorScheme.light(
                              primary: Color(0xffffbc00),
                              primaryVariant: Colors.black,
                              secondaryVariant: Colors.black,
                              onSecondary: Colors.black,
                              onPrimary: Colors.white,
                              surface: Colors.black,
                              onSurface: Colors.black,
                              secondary: Colors.black),
                              dialogBackgroundColor: Colors.white,
                        ),
                        child: child ??Text(""),
                      );
                    }
                    initialDate: selectedDate,
                    firstDate: DateTime(1960, 8),
                    lastDate: DateTime.now());
                if (picked != null && picked != selectedDate)
                  setState(() {
                    selectedDate = picked;
                     
                
                    String da = picked.day.toString() +
                        "-" +
                        picked.month.toString() +
                        "-" +
                        picked.year.toString();
                    dateOfBirth.text = da;
                  });}
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-30
                  • 2020-02-05
                  • 1970-01-01
                  相关资源
                  最近更新 更多