setState не работает на Dynami c Список виджетов для обновления заголовка одного виджета - PullRequest
0 голосов
/ 07 января 2020

Я создал кнопку, которая добавляет новый виджет 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(() {});
      },
    );
  }
}
...