Reputation: 1354
I think this is the right question. I have encountered the problem of wanting to keep my code super condensed, and simple for the sake of my demo project. And I am using two stateless widgets which I would like to have communicate, that is I want one widget to reload the other on user input.
Proviso Note: I'm getting acquainted to using GetX mainly for state management so I would like to try to always use stateless widgets. Please keep this in mind in your answer. I know I can solve this with setState() stateful widget. I also know I can solve this with a controller class extending GetXController() or even provider. However I am simply curious if what I'm trying to do is even possible without these obvious solutions...
So.. Question is:
Is it possible to have this widget's rangeStart & rangeEnd (when changed by user date selection) rebuild the text widget in the next widget below?
import 'package:flutter/material.dart';
import 'package:date_range_picker/date_range_picker.dart' as DateRangePicker;
// ignore: must_be_immutable
class DateRange extends StatelessWidget {
DateTime rangeStart = DateTime.now().subtract(Duration(days: 7));
DateTime rangeEnd = DateTime.now();
@override
Widget build(BuildContext context) {
return IconButton(
color: Colors.white,
icon: Icon(Icons.calendar_today),
onPressed: () async {
final List<DateTime> picked = await DateRangePicker.showDatePicker(
context: context,
initialFirstDate: DateTime.now().subtract(Duration(days: 7)),
initialLastDate: DateTime.now(),
firstDate: DateTime(2015),
lastDate: DateTime(DateTime.now().year + 2));
if (picked != null && picked.length == 2) {
rangeStart = picked.first;
rangeEnd = picked.last;
}
});
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:linechart/add_data_button.dart';
import 'package:linechart/date_range.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:intl/intl.dart';
class LineChartScreen extends StatelessWidget {
final DateRange dateRange = Get.put(DateRange());
@override
Widget build(BuildContext context) {
String startDate = DateFormat.yMMMMd('en_US').format(dateRange.rangeStart);
String endDate = DateFormat.yMMMMd('en_US').format(dateRange.rangeEnd);
return Scaffold(
appBar: AppBar(
title: Text('GRAPH --- Range: $startDate - $endDate'),
backgroundColor: Colors.lightBlue,
actions: [
AddDataButton(),
DateRange(),
],
),
body: Column(...),
);
}
}
Upvotes: 0
Views: 534
Reputation: 2229
This old post explains that:
A StatelessWidget will never rebuild by itself (but can from external events). A StatefulWidget can. That is the golden rule.
So you need some mechanism to cause a StatelessWidget
to rebuild, and as you say there are many of these.
I like using flutter_hooks
as a simple mechanism for managing such private state. Here is code for your example that uses it. In the code:
useState
to define/access its stateThe code:
import 'package:flutter/material.dart';
import 'package:date_range_picker/date_range_picker.dart' as DateRangePicker;
import 'package:intl/intl.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
// ignore: must_be_immutable
class DateRangeWidget extends StatelessWidget {
Function _setDateRange;
DateRangeWidget(this._setDateRange);
DateTime rangeStart = DateTime.now().subtract(Duration(days: 7));
DateTime rangeEnd = DateTime.now();
@override
Widget build(BuildContext context) {
return IconButton(
color: Colors.white,
icon: Icon(Icons.calendar_today),
onPressed: () async {
final List<DateTime> picked = await DateRangePicker.showDatePicker(
context: context,
initialFirstDate: DateTime.now().subtract(Duration(days: 7)),
initialLastDate: DateTime.now(),
firstDate: DateTime(2015),
lastDate: DateTime(DateTime.now().year + 2));
if (picked != null && picked.length == 2) {
rangeStart = picked.first;
rangeEnd = picked.last;
_setDateRange(rangeStart, rangeEnd);
}
});
}
}
class DateRange {
DateTime rangeStart, rangeEnd;
DateRange(this.rangeStart, this.rangeEnd);
}
class LineChartScreen extends HookWidget {
// final DateRange dateRange = Get.put(DateRange());
@override
Widget build(BuildContext context) {
final dateRange = useState(
DateRange(DateTime.now().subtract(Duration(days: 7)), DateTime.now()));
void _setDateRange(rangeStart, rangeEnd) {
dateRange.value = DateRange(rangeStart, rangeEnd);
}
String startDate =
DateFormat.yMMMMd('en_US').format(dateRange.value.rangeStart);
String endDate =
DateFormat.yMMMMd('en_US').format(dateRange.value.rangeEnd);
return Scaffold(
appBar: AppBar(
title: Text('GRAPH --- Range: $startDate - $endDate'),
backgroundColor: Colors.lightBlue,
actions: [
// AddDataButton(),
DateRangeWidget(_setDateRange),
],
),
body: Column(
children: [
Text(startDate),
Text(endDate),
],
),
);
}
}
Upvotes: 1