I am trying to use Flutter Riverpod together with the Date Range Picker.
- I have a list of Trips which when clicked on, open up the Trip Page.
- On the trip page, the user can view the start / end dates
- They can then click on a button, which brings up the Date Range Picker widget
- I want the user to be able to change the date range, and this be reflected on the screen (and eventually saved back against the Trip object)
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
void main() {
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Riverpod DateRange Picker',
home: HomeScreen(),
);
}
}
class Trip {
final String name;
final DateTimeRange dateTimeRange;
Trip(this.name, this.dateTimeRange);
}
class HomeScreen extends ConsumerWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
Set<Trip> trips = {
Trip('Test 1',
DateTimeRange(start: DateTime(2023, 1, 3), end: DateTime(2023, 1, 6)))
};
return Scaffold(
appBar: AppBar(title: const Text('Riverpod DateRange Picker')),
body: ListView(
children: [
for (final trip in trips)
ListTile(
title: Text(trip.name),
onTap: () {
Navigator.push(
context,
MaterialPageRoute<void>(
builder: (BuildContext context) =>
TripScreen(trip: trip)));
},
),
],
),
);
}
}
class TripScreen extends ConsumerWidget {
const TripScreen({Key? key, required this.trip}) : super(key: key);
final Trip trip;
@override
Widget build(BuildContext context, WidgetRef ref) {
void _showDateRangePicker() async {
final DateTimeRange? result = await showDateRangePicker(
context: context,
locale: const Locale('en', 'GB'),
initialDateRange: trip.dateTimeRange,
saveText: 'Done',
firstDate: DateTime(2022, 1, 1),
lastDate: DateTime(2030, 12, 31),
);
if (result != null) {
print(result);
}
}
return WillPopScope(
onWillPop: () {
Navigator.pop(context);
return Future.value(false);
},
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(trip.name),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
IconButton(
icon: const Icon(Icons.calendar_month),
onPressed: () {
_showDateRangePicker();
},
),
Text(
'Start: ${DateFormat('dd/MM/yyyy').format(trip.dateTimeRange.start)}'),
Text(
'End: ${DateFormat('dd/MM/yyyy').format(trip.dateTimeRange.end)}'),
],
))));
}
}
Any help would be much appriciated.
Thanks.
I've created this using Provider but I would like to use Riverpod.
I created "tripsProvider" instance of StateProvider that holds all trip data, like in your case only one value. Home screen watching that provider and displaying data in ListView, when user select item in list I pass index of item and watch that single item on new screen (copy of yours TripScreen). When user update the data of single item I update that list, so update is available on TripScreen and HomeScreen. I also still learning riverpod but hope my answer can help you.