DatePicker adalah widget yang sudah disediakan oleh Flutter. Masih menggunakan aplikasi expense tracker, kita akan tambahkan DatePicker pada form_expense.dart

Fungsi showDatePicker memerlukan parameter context, initialDate, firsDate dan lastDate. initialDate adalah tanggal yg aktif saat DatePicker ditampilkan, firstDate adalah tanggal awal yang bisa dipilih dan lastDate adalah tanggal akhir yang bisa dipilih.
Pada code dibawah, Date Picker akan menampilkan tanggal yang bisa dipilih dari awal tahun 2020 hingga tanggal saat ini, dengan tanggal aktif adalah tanggal hari ini.
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime.now());
Berikut implementasi showDatePicker pada form_expense.dart
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class FormExpense extends StatefulWidget {
final Function addExpenseH;
FormExpense(this.addExpenseH);
@override
_FormExpenseState createState() => _FormExpenseState();
}
class _FormExpenseState extends State<FormExpense> {
final titleCtrl = TextEditingController();
final amountCtrl = TextEditingController();
DateTime _datePicked;
void _submitForm() {
final inpTitle = titleCtrl.text;
final inpAmount = double.parse(amountCtrl.text);
if (inpAmount <= 0 || inpTitle.isEmpty || _datePicked == null) {
return;
}
widget.addExpenseH(
titleCtrl.text,
double.parse(amountCtrl.text),
_datePicked,
);
Navigator.of(context).pop();
}
void _showDatePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime.now())
.then((value) {
if (value == null) {
return;
}
setState(() {
_datePicked = value;
});
});
}
@override
Widget build(BuildContext context) {
return Card(
child: Container(
padding: EdgeInsets.all(7),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
TextField(
decoration: InputDecoration(labelText: 'Title'),
// onChanged: (val) => titleInp = val,
controller: titleCtrl,
onSubmitted: (_) => _submitForm,
),
TextField(
decoration: InputDecoration(labelText: 'Amount'),
// onChanged: (val) => amountInp = val,
controller: amountCtrl,
keyboardType: TextInputType.number,
onSubmitted: (_) => _submitForm,
),
Container(
height: 60,
child: Row(
children: <Widget>[
Expanded(
child: Text(
_datePicked == null
? 'Pilih tanggal'
: 'Tanggal: ${DateFormat.yMd().format(_datePicked)}',
style: TextStyle(color: Colors.black),
),
),
FlatButton(
child: Text(
'Choose Date',
style: TextStyle(fontWeight: FontWeight.bold),
),
textColor: Theme.of(context).accentColor,
onPressed: () => _showDatePicker(),
),
],
),
),
RaisedButton(
onPressed: _submitForm,
color: Theme.of(context).accentColor,
child: Text('Add Expense'),
textColor: Colors.white,
),
],
),
),
);
}
}
Pembahasan Code
Untuk menampilkan DatePicker, kita buat fungsi baru yaitu _showDatePicker() yang akan dipanggil saat FlatButton(‘Choose Date’) ditekan.
Fungsi showDatePicker kita gunakan fungsi then untuk menerima hasil input user tanpa harus menunggu. Artinya aplikasi tetap berjalan, tidak bottleneck.
Bila user memilih tanggal, maka screen akan direbuild dengan memanggil fungsi setState().
//fungsi _showDatePicker di form_expense.dart
void _showDatePicker() {
showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2020),
lastDate: DateTime.now())
.then((value) {
if (value == null) {
return;
}
setState(() {
_datePicked = value;
});
});
}
Pada fungsi submit form juga kita tambahkan validasi _datePicked == null dan ditambahkan sebagai parameter saat memanggil fungsi addExpense.
//fungsi _submitForm di form_expense.dart
void _submitForm() {
final inpTitle = titleCtrl.text;
final inpAmount = double.parse(amountCtrl.text);
if (inpAmount <= 0 || inpTitle.isEmpty || _datePicked == null) {
return;
}
widget.addExpenseH(
titleCtrl.text,
double.parse(amountCtrl.text),
_datePicked,
);
Navigator.of(context).pop();
}
Karena ada penambahan parameter addExpense, maka fungsi addExpense yang ada di main.dart harus diubah juga.
//fungsi _addNewExpense di main.dart
void _addNewExpense(String newTitle, double newAmount, DateTime newDate) {
final newExpense = Trans(
id: DateTime.now().toString(),
title: newTitle,
amount: newAmount,
txdate: newDate);
setState(() {
_trans.add(newExpense);
});
}