Reputation: 341
I have an array with certain dates.
I want to disable these dates in the date picker and also change the color. How to do this?
Upvotes: 2
Views: 9302
Reputation: 51
I encountered the same problem. After going back and forth, I did the following:
Created a list of specific dates:
static var unavailableDates = ["2020-08-14", "2020-08-20", "2020-08-13","2020-08-21","2020-08-23"];
Created an initial date variable:
static DateTime initialDate = DateTime.now();
formatted the initial date to get rid of the timestamp:
static DateFormat dateFormat = new DateFormat("yyyy-MM-dd");
String formattedDate = dateFormat.format(initialDate);
Put my unavailable dates in order:
unavailableDates.sort(((a, b) => a.compareTo(b)));
Added a way to verify the initial date does not fall on the disabled date. This jumps to the next available date. If you do not have something in place to verify unavailable date and initial date is not the same, you will get an exception:
for(var unavdate in unavailableDates){
if (unavdate.compareTo(formattedDate) == 0) {
formattedDate = unavdate;
fromStringDate = DateTime.parse(formattedDate);
initialDate = fromStringDate.add(new Duration(days: 1));
formattedDate = dateFormat.format(initialDate);
}
}
Created a day predicate function:
bool setDayPredicate(DateTime val) {
//this allows certain dates to be greyed out based on availability
String Dates = dateFormat.format(val); //formatting passed in value
return !unavailableDates.contains(Dates);
}
Put it all together:
date = await showDatePicker(
context: context,
initialDate: initialDate,
firstDate: new DateTime.now(),
lastDate: new DateTime.now().add(new Duration(days: 30)),
selectableDayPredicate: setDayPredicate, });
Upvotes: 4
Reputation: 5086
You can use selectableDayPredicate
property. For colors, you can change it by themes.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DateTime selectedDate = DateTime(2020, 1, 14);
// DatePicker will call this function on every day and expect
// a bool output. If it's true, it will draw that day as "enabled"
// and that day will be selectable and vice versa.
bool _predicate(DateTime day) {
if ((day.isAfter(DateTime(2020, 1, 5)) &&
day.isBefore(DateTime(2020, 1, 9)))) {
return true;
}
if ((day.isAfter(DateTime(2020, 1, 10)) &&
day.isBefore(DateTime(2020, 1, 15)))) {
return true;
}
if ((day.isAfter(DateTime(2020, 2, 5)) &&
day.isBefore(DateTime(2020, 2, 17)))) {
return true;
}
return false;
}
Future<void> _selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
selectableDayPredicate: _predicate,
firstDate: DateTime(2019),
lastDate: DateTime(2021),
builder: (context, child) {
return Theme(
data: ThemeData(
primaryColor: Colors.orangeAccent,
disabledColor: Colors.brown,
textTheme:
TextTheme(body1: TextStyle(color: Colors.blueAccent)),
accentColor: Colors.yellow),
child: child,
);
});
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text("${selectedDate.toLocal()}".split(' ')[0]),
SizedBox(
height: 20.0,
),
RaisedButton(
onPressed: () => _selectDate(context),
child: Text('Select date'),
),
],
),
),
);
}
}
Upvotes: 6