Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 有没有可能在没有状态管理器的情况下实现两个无状态小部件之间的状态管理?_Flutter_State Management_Statelesswidget - Fatal编程技术网

Flutter 有没有可能在没有状态管理器的情况下实现两个无状态小部件之间的状态管理?

Flutter 有没有可能在没有状态管理器的情况下实现两个无状态小部件之间的状态管理?,flutter,state-management,statelesswidget,Flutter,State Management,Statelesswidget,我认为这是一个正确的问题。为了我的演示项目,我遇到了一个问题,那就是想要让我的代码保持超级精简和简单。我正在使用两个无状态的小部件,我希望它们能够通信,也就是说,我希望一个小部件在用户输入时重新加载另一个小部件 但书注意:我已经熟悉了GetX主要用于状态管理,所以我想尝试始终使用无状态小部件。请在回答时记住这一点。我知道我可以用setState()有状态小部件解决这个问题。我还知道,我可以通过扩展GetXController()甚至提供程序的控制器类来解决这个问题。然而,我只是好奇,如果没有这些

我认为这是一个正确的问题。为了我的演示项目,我遇到了一个问题,那就是想要让我的代码保持超级精简和简单。我正在使用两个无状态的小部件,我希望它们能够通信,也就是说,我希望一个小部件在用户输入时重新加载另一个小部件

但书注意:我已经熟悉了GetX主要用于状态管理,所以我想尝试始终使用无状态小部件。请在回答时记住这一点。我知道我可以用setState()有状态小部件解决这个问题。我还知道,我可以通过扩展GetXController()甚至提供程序的控制器类来解决这个问题。然而,我只是好奇,如果没有这些显而易见的解决方案,我想做的事情是否可能

所以。。问题是:

是否可以让此小部件的rangeStart和rangeEnd(当用户日期选择更改时)在下面的下一个小部件中重建文本小部件?

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;
          }
        });
  }
}
这说明:

无状态小部件永远不会自行重建(但可以从外部重建) 事件)。一个有状态的小部件可以。这是金科玉律

因此,您需要某种机制来导致
无状态widget
重新生成,正如您所说的,有很多这样的机制

我喜欢使用
flatter\u hooks
作为管理这种私有状态的简单机制。下面是使用它的示例的代码。在守则中:

  • 父窗口小部件调用
    useState
    来定义/访问其状态
  • 子部件调用回调来更新状态,从而导致父部件重新生成
守则:

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),
        ],
      ),
    );
  }
}
导入“包装:颤振/材料.省道”;
将“package:date\u range\u picker/date\u range\u picker.dart”导入为DateRange picker;
导入“包:intl/intl.dart”;
进口“包装:颤振钩/颤振钩.省道”;
//忽略:必须是不可变的
类DateRangeWidget扩展了无状态Widget{
函数_setDateRange;
DateRangeWidget(此._setDateRange);
DateTime rangeStart=DateTime.now().subtract(持续时间(天:7));
DateTime rangeEnd=DateTime.now();
@凌驾
小部件构建(构建上下文){
返回图标按钮(
颜色:颜色,白色,
图标:图标(今天的图标、日历),
onPressed:()异步{
最终选择列表=等待DateRangePicker.showDatePicker(
上下文:上下文,
initialFirstDate:DateTime.now().subtract(持续时间(天: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);
}
});
}
}
类日期范围{
日期时间范围开始,范围结束;
DateRange(this.rangeStart、this.rangeEnd);
}
类LineChartScreen扩展了Widget{
//final DateRange DateRange=Get.put(DateRange());
@凌驾
小部件构建(构建上下文){
最终日期范围=useState(
DateRange(DateTime.now().subtract(持续时间(天:7)),DateTime.now());
void\u setDateRange(rangeStart、rangeEnd){
dateRange.value=dateRange(rangeStart,rangeEnd);
}
字符串起始日期=
DateFormat.yMMMMd('en_US').format(dateRange.value.rangeStart);
字符串结束日期=
DateFormat.yMMMMd('en_US').format(dateRange.value.rangeEnd);
返回脚手架(
appBar:appBar(
标题:文本('GRAPH---Range:$startDate-$endDate'),
背景颜色:颜色。浅蓝色,
行动:[
//AddDataButton(),
DateRangeWidget(_setDateRange),
],
),
正文:专栏(
儿童:[
文本(起始日期),
文本(结束日期),
],
),
);
}
}

很好,很简单,我将研究挂钩。谢谢你的帮助:)
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),
        ],
      ),
    );
  }
}