可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I’m using the showDatePicker()
method to display a date picker in my flutter application. How do I customize the colors of the date picker?
Here is my theme's code:
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
)
);
}
Here is my code for wrapping the page in the theme:
@override
Widget build(BuildContext context) {
[...]
return new CustomTheme(
new Scaffold(
[...]
)
);
}
回答1:
I assume that you want to customize the date picker differently from your main theme. Normally, date picker follow your main theme.
If so, wrap the button that triggers the action in a Builder
inside a Theme
. For example, here's a FAB that pops up an orange date picker (in a light material app theme), inheriting the rest from the main theme.
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)),
),
),
),
),
Check the source code of date_picker.dart to see which parts of the Theme affect different aspects of the date picker.
If you just want the picker to follow the main theme, here's a working example
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()),
),
);
}
If you want to apply the theme to the whole app, it can be added most concisely (without the need for the CustomTheme class) to the Material app:
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(),
),
);
}
回答2:
There is builder parameter available with showDatePicker() method.
try this:
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,
);
},
);
and you will get something like this:
回答3:
If you only want to change the theme data for the datePicker you need to wrap the widget responsible for showing the datePicker inside a Builder widget and ultimately wrap it all inside a Theme widget as shown below:
PS: But at the time I was writing this answer, the text color ("OK/CANCEL") was not accepted. It is a issue in the flutter framework.
19623 is the issue.
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))
),
),
);
},
),
);
}
Output
Hope this helps!!!
回答4:
The above answers are working except for the Ok/Cancel buttons. Just adding this in case somebody needs help on customizing it. It is a combination of colorScheme and 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,
);
},
);