Я создал кнопку, которая добавляет новый виджет ListTile в список виджетов. Затем я показываю их с помощью столбца. Внутри ListTile у меня есть метод onTap, который открывает другую модальную таблицу для отображения времени. Мое намерение состоит в том, чтобы, если пользователь выбирает время, я бы изменил название этого ListTile. Я использовал setState, но он не работает. Вот код:
import 'package:basicflutter/time_selection/time_selection.dart';
import 'package:basicflutter/time_selection/white_container.dart';
import 'package:fixnum/fixnum.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
class DateGenerate extends StatefulWidget {
@override
State<StatefulWidget> createState() => DateGenerateState();
}
class DateGenerateState extends State<DateGenerate> {
bool busy = false;
int sessionTime;
int startingTimeinHour;
double totalTimeDivision;
List<DateTime> allTimeSchedule;
List<Widget> timeWidgets = new List<Widget>();
@override
void initState() {
sessionTime = 30;
startingTimeinHour = 60 - sessionTime;
totalTimeDivision = (24 * 60) / sessionTime;
allTimeSchedule = new List<DateTime>();
generateDate();
}
void generateDate() {
DateTime now = new DateTime.now();
DateTime initial =
new DateTime(now.year, now.month, now.day, 11, startingTimeinHour, 0);
for (int i = 0; i < totalTimeDivision; i++) {
initial = initial.add(new Duration(minutes: sessionTime));
allTimeSchedule.add(initial);
}
}
@override
void didUpdateWidget(Widget oldWidget) {
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Time Selection"),
),
body: SingleChildScrollView(
child: Column(
children: buildChildren(),
),
),
);
}
List<Widget> buildChildren() {
return [
SizedBox(height: 10.0),
Column(
children: timeWidgets,
),
SizedBox(height: 10.0),
Container(
alignment: Alignment.center,
child: RaisedButton(
child: Icon(Icons.add),
onPressed: () {
timeWidgets.add(buildSelectTime());
if (mounted) setState(() {});
},
),
)
];
}
Widget buildSelectTime() {
List<DateTime> selectedDate = new List<DateTime>();
return Card(
child: ListTile(
title: Text(
selectedDate.length == 0 ? 'Choose time range' : 'Seleted range'),
trailing: Icon(Icons.chevron_right),
onTap: () {
showModalBottomSheet(
context: context,
builder: (_) => SelectionWidget(
title: 'Choose your times',
values: allTimeSchedule,
selected: selectedDate,
onSelect: (value) {
selectedDate.clear();
selectedDate.add(value[0]);
selectedDate.add(value[value.length - 1]);
setState(() {});
},
),
);
},
),
);
}
}
Если вы хотите запустить код в своем проекте, вам также понадобится этот код, который представляет собой SelectionWidget.
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class SelectionWidget extends StatefulWidget {
final String title;
final List<DateTime> selected;
final List<DateTime> values;
final Function(List<DateTime>) onSelect;
SelectionWidget({
@required this.onSelect,
@required this.values,
this.selected,
this.title,
});
@override
State<StatefulWidget> createState() => _SelectionWidgetState();
}
class _SelectionWidgetState extends State<SelectionWidget> {
final current = Set();
int startTimeIndex;
int endTimeIndex;
bool enable = true;
bool rangeChoosen;
@override
void initState() {
super.initState();
current.addAll(widget.selected);
widget.values.length == 0 ? rangeChoosen = false : rangeChoosen = true;
}
@override
Widget build(BuildContext context) {
return RawMaterialButton(
onPressed: () {},
splashColor: Colors.transparent,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
child: Stack(
children: <Widget>[
SingleChildScrollView(
padding: EdgeInsets.only(bottom: 50.0),
child: buildView(),
),
Positioned(
bottom: 0.0,
left: 0.0,
right: 0.0,
height: 60.0,
child: buildDoneButton(),
),
Positioned(
top: 0.0,
right: 0.0,
child: buildCloseButton(),
),
],
),
);
}
Widget buildView() {
final children = <Widget>[
buildTitle(),
Divider(height: 20.0),
];
children.addAll(
widget.values.map(buildListTile),
);
return Column(
mainAxisSize: MainAxisSize.min,
children: children,
);
}
Widget buildCloseButton() {
return RawMaterialButton(
fillColor: Colors.white,
shape: CircleBorder(),
child: Icon(Icons.close),
onPressed: () => Navigator.pop(context),
);
}
Widget buildDoneButton() {
return Container(
alignment: Alignment.center,
padding: EdgeInsets.all(8.0),
child: SizedBox.expand(
child: RaisedButton(
color: Colors.black,
child: Text(
'Done',
textScaleFactor: 1.15,
style: TextStyle(color: Colors.white),
),
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
Widget buildTitle() {
if (widget.title == null || widget.title == '') {
return Container();
}
return Container(
padding: EdgeInsets.fromLTRB(10.0, 10.0, 50.0, 0.0),
child: Text(
widget.selected.length == 0 ? widget.title:
'${new DateFormat("hh:mm a").format(widget.selected[0])} - ${new DateFormat("hh:mm a").format(widget.selected[widget.selected.length-1])}',
style: TextStyle(
fontSize: 22.0,
fontWeight: FontWeight.w300,
),
),
);
}
Widget buildListTile(value) {
IconData icon = current.contains(value)
? Icons.check_box
: Icons.check_box_outline_blank;
return ListTile(
leading: Icon(
icon,
color: Colors.black,
),
title: Text(new DateFormat("hh:mm a").format(value)),
onTap: () {
int index = widget.values.indexOf(value);
if (current.length == 0 && rangeChoosen == false) {
current.add(value);
startTimeIndex = index;
} else if (current.length == 1 && rangeChoosen == false) {
rangeChoosen = true;
endTimeIndex = index;
current.clear();
for (int i = startTimeIndex; i <= endTimeIndex; i++) {
current.add(widget.values[i]);
}
} else if (rangeChoosen == true) {
rangeChoosen = false;
current.clear();
current.add(value);
startTimeIndex = index;
}
List<DateTime> tempDate = new List<DateTime>();
for (int i = 0; i < current.toList().length; i++) {
tempDate.add(current.toList()[i]);
}
widget.onSelect(tempDate);
if (mounted) setState(() {});
},
);
}
}