如何实现窗口小部件的标准行为

问题描述 投票:0回答:1

我想解决以下情况:

正在显示(推送)屏幕/小部件。这个屏幕需要:

  • 在第一次创建时执行长任务(请求)
  • 在执行任务时显示加载(reqeusting)
  • 如果需要,显示错误对话框(失败请求)
  • 任务完成后相应地更新列表
  • 有一个外部触发器来更新和重新启动长任务(再次请求数据+加载和警报包括在内)

——————————————————————————

我得出的结论是,如果没有:

  • 显示错误对话框的延迟机制(addPostFrameCallback或Future.delayed)
  • 用于处理组件行为的状态机制(初始/加载/卸载/完成)

值得一提的是,颤振对我来说是新的,我可能会遗漏关于框架的重要信息。

——————————————————————————

以上是上述结论的推理。

错误对话限制:

  • 从构建方法中,您无法显示对话框,因为您需要先返回一个小部件(例如,给定任务失败,您需要显示一个对话框);否则会提示错误

// ... // flutter:在构建期间调用的setState()或markNeedsBuild()。 // flutter:这个Overlay小部件无法标记为需要构建,因为框架已经在// setState()或markNeedstoBuild()// ...

  • 如果你在构建方法之前执行任务并且它失败了,你将再次遇到同样的错误// ... //颤振:在// flutter:_VacationsViewState.initState()完成之前调用inheritFromWidgetOfExactType(_LocalizationsScope)或inheritFromElement()。 // ...
  • 构建方法无法触发任务,因为此方法被调用很多次。

州指标限制:

  • 在构建窗口小部件组件之后,如果任务再次触发执行,则组件将无法知道除非具有此状态机制,否则需要显示加载指示器。这种状态机制意味着调用setState或使用streambuilders(基于状态)。

——————————————————————————

其他片段可以说明这些情况:

// using FutureBuilder
Widget build(BuildContext context) {
    return FutureBuilder(
    future: someFuture,
    builder: (BuildContext context, AsyncSnapshot snapshot) {
        // Here we need to display loading while task is not finished and a dialog if it fails
        // dialog needs to be performed with a delay
        // triggering again the build will need to have a setState called to “reload”
    });
}

// using StreamBuilder
Widget build(BuildContext context) {
    return StreamBuilder<void>(
        stream: status,
        builder: (BuildContext context, AsyncSnapshot<void> status) {
           //  status can represent states (loading/finished/… )
       // dialog needs to be displayed with a delay in case the error the current state
    });
}

——————————————————————————

达成最终妥协:

  • 使用一些状态机制与状态描述符和可能的流或直接使用setState
  • 使用对话框的延迟机制

——————————————————————————

dart flutter dialog loading code-design
1个回答
0
投票

我无法真正尝试这一点,但这不能解决你的问题吗?

使用setState有什么问题?

Future _calculation;

initState(){
  super.initState();
  _calculation = fetchData();
}


  FutureBuilder<String>(
  future: _calculation, // a previously-obtained Future<String> or null
  builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
    switch (snapshot.connectionState) {
      case ConnectionState.none:
        return Text('Press button to start.');
      case ConnectionState.active:
      case ConnectionState.waiting:
        return Text('Awaiting result...');
      case ConnectionState.done:
        if (snapshot.hasError)
          //show your error dialog

          // show result
        return Text('Result: ${snapshot.data}');
    }
    return null; // unreachable
  },
);

  new RaisedButton(
  child: const Text('Reload'),
  color: Theme.of(context).accentColor,
  elevation: 4.0,
  splashColor: Colors.blueGrey,
  onPressed: () {
    setState((
      // this will trigger the FutureBuilder and update/show the result
      _calculation = fetchData();
    ));
  },
),
© www.soinside.com 2019 - 2024. All rights reserved.