从Flutter中暂时从树中删除时保留小部件状态 [英] Preserve widget state when temporarily removed from tree in Flutter

查看:73
本文介绍了从Flutter中暂时从树中删除时保留小部件状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试保留小部件的状态,因此,如果我从小部件树中暂时删除有状态的小部件,然后在以后重新添加它,则该小部件将具有与我之前相同的状态删除它.这是我的简化示例:

I'm trying to preserve the state of a widget, so that if I temporarily remove the stateful widget from the widget tree, and then re-add it later on, the widget will have the same state as it did before I removed it. Here's a simplified example I have:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool showCounterWidget = true;
  @override
  Widget build(BuildContext context) {

    return Material(
      child: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            showCounterWidget ? CounterButton(): Text("Other widget"),
            SizedBox(height: 16,),
            FlatButton(
              child: Text("Toggle Widget"),
              onPressed: (){
                setState(() {
                showCounterWidget = !showCounterWidget;
              });
                },
            )
          ],
        ),
      ),
    );
  }
}

class CounterButton extends StatefulWidget {
  @override
  _CounterButtonState createState() => _CounterButtonState();
}

class _CounterButtonState extends State<CounterButton> {
  int counter = 0;

  @override
  Widget build(BuildContext context) {
    return MaterialButton(
      color: Colors.orangeAccent,
      child: Text(counter.toString()),
      onPressed: () {
        setState(() {
          counter++;
        });
      },
    );
  }
}

理想情况下,我不希望重置状态,因此计数器不会重置为0,我如何保存计数器小部件的状态?

Ideally, I would not want the state to reset, therefor the counter would not reset to 0, how would I preserve the state of my counter widget?

推荐答案

小部件暂时从树中删除时,其状态会松散的原因,正如约书亚所说,是因为它的元素/状态会松散.

The reason why the widget loose its state when removed from the tree temporarily is, as Joshua stated, because it loose its Element/State.

现在您可能会问:

我是否可以缓存元素/状态,以便下次插入窗口小部件时,可以重用前一个窗口小部件,而不是重新创建它们?

Can't I cache the Element/State so that next time the widget is inserted, it reuse the previous one instead of creating them anew?

这是一个有效的主意,但不是.你不能Flutter认为这是一种反模式,在这种情况下会抛出异常.

This is a valid idea, but no. You can't. Flutter judges that as anti-pattern and will throw an exception in that situation.

您应该做的是将窗口小部件保持在窗口小部件树中处于禁用状态.

What you should instead do is to keep the widget inside the widget tree, in a disabled state.

要实现这种目标,您可以使用以下小部件:

To achieve such thing, you can use widgets like:

  • IndexedStack
  • 可见性/台下

这些小部件将允许您将小部件保留在小部件树中(以便保持其状态),但是禁用其渲染/动画/语义.

These widgets will allow you to keep a widget inside the widget tree (so that it keeps its state), but disable its rendering/animations/semantics.

因此,而不是:

Widget build(context) {
  if (condition)
    return Foo();
  else
    return Bar();
}

这会使 Foo / Bar 在它们之间切换时失去状态

which would make Foo/Bar loose their state when switching between them

这样做:

IndexedStack(
  index: condition ? 0 : 1, // switch between Foo and Bar based on condition
  children: [
    Foo(),
    Bar(),
  ],
)

使用此代码,然后 Foo / Bar 在它们之间来回移动时,不会松开它们的状态.

Using this code, then Foo/Bar will not loose their state when doing a back and forth between them.

这篇关于从Flutter中暂时从树中删除时保留小部件状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆