简体   繁体   English

如何将颤动页面(小部件)重置为初始状态(应用程序首次构建时的状态)

[英]How to reset a flutter Page (Widget) to initial state(state when the app was first Built)

假设我的页面上有一些滑块和开关,我更改了它们的状态并修改了它们,我知道我们执行setState来显示小部件树的更改状态并重建它,但我想知道是否有办法撤消所有这些更改并返回到初始状态(应用程序最初构建时的状态)?

If you want to do things out of the box如果你想开箱即用

在此处输入图片说明


void main() => runApp(MaterialApp(home: DummyWidget()));

class DummyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) => HomePage();
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _enabled = false; // For Switch
  double _value = 0; // For Slider

  // This is the trick!
  void _reset() {
    Navigator.pushReplacement(
      context,
      PageRouteBuilder(
        transitionDuration: Duration.zero,
        pageBuilder: (_, __, ___) => DummyWidget(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          Switch(
            value: _enabled,
            onChanged: (newValue) => setState(() => _enabled = newValue),
          ),
          Slider(
            value: _value,
            onChanged: (newValue) => setState(() => _value = newValue),
          ),
          FlatButton(
            onPressed: _reset,
            child: Text('RESET'),
          ),
        ],
      ),
    );
  }
}

A better approach might be with keys.更好的方法可能是使用密钥。 Here's the key approach这是关键方法

A simple trick would be to pop and push with the same route.一个简单的技巧是使用相同的路线弹出和推送。 Like this:像这样:

Navigator.popAndPushNamed(context, "same_route");

Screenshot:截屏:

在此处输入图片说明


Using key to change the state.使用key来改变状态。

void main() => runApp(MaterialApp(home: HomePage()));

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: KeyedSubtree(
        key: ValueKey<int>(_count),
        child: Column(
          children: [
            MainPage(),
            FlatButton(
              onPressed: () => setState(() => ++_count),
              child: Text('RESET'),
            )
          ],
        ),
      ),
    );
  }
}

class MainPage extends StatefulWidget {
  @override
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  bool _enabled = false; // For Switch
  double _value = 0; // For Slider.

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Switch(
          value: _enabled,
          onChanged: (newValue) => setState(() => _enabled = newValue),
        ),
        Slider(
          value: _value,
          onChanged: (newValue) => setState(() => _value = newValue),
        ),
      ],
    );
  }
}

Here is one way of many to reset to the initial data这是重置为初始数据的众多方法中的一种

在此处输入图片说明

import 'package:flutter/material.dart';

List<String> initialData = ['First', 'Second', 'Third'];

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: Example(),
    );
  }
}

class Example extends StatefulWidget {
  @override
  _ExampleState createState() => _ExampleState();
}

class _ExampleState extends State<Example> {
  List<String> items = [];

  @override
  void initState() {
    fillInitialData();
    super.initState();
  }

  fillInitialData() {
    items.addAll(initialData);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Example')),
      body: Column(
        children: <Widget>[
          Expanded(
            child: ListView.builder(
              itemCount: items.length,
              itemBuilder: (context, index) {
                return Card(
                  child: Padding(
                    padding: EdgeInsets.all(16.0),
                    child: Text(items[index]),
                  ),
                );
              },
            ),
          ),
          Row(
            children: <Widget>[
              FlatButton(
                onPressed: () {
                  setState(() {
                    items.add('A new item');
                  });
                },
                child: Text('Add an item'),
              ),
              FlatButton(
                onPressed: () {
                  setState(() {
                    items.clear();
                    fillInitialData();
                  });
                },
                child: Text('Reset'),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

Screenshot:截屏:

在此处输入图片说明

Full Code:完整代码:

void main() {
  runApp(
    MaterialApp(
      // Passing initial values
      home: HomePage(enabled: false, value: 0),
    ),
  );
}

class HomePage extends StatefulWidget {
  final bool enabled;
  final double value;

  HomePage({this.enabled = false, this.value = 0});

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

class _HomePageState extends State<HomePage> {
  bool _initialEnabled, _enabled; // For Switches
  double _initialValue, _value; // For Sliders

  @override
  void initState() {
    super.initState();

    // Assign them once (initial data)
    _initialEnabled ??= widget.enabled;
    _initialValue ??= widget.value;

    // These values can be changed by respective widgets
    _enabled = _initialEnabled;
    _value = _initialValue;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          children: [
            Switch(
              value: _enabled,
              onChanged: (value) => setState(() => _enabled = value),
            ),
            Slider(
              value: _value,
              onChanged: (value) => setState(() => _value = value),
            ),
            RaisedButton(
              onPressed: () {
                setState(() {
                  // Resetting the values to initial ones which were passed
                  _enabled = _initialEnabled;
                  _value = _initialValue;
                });
              },
              child: Text('RESET'),
            ),
          ],
        ),
      ),
    );
  }
}

You can call YourStateClass.initState() to revert to its original initialized state.您可以调用YourStateClass.initState()以恢复到其原始初始化状态。

Also make sure that when you construct your state, you will want to initialize all of your variables in the void initState() function.还要确保在构造状态时,您需要在void initState()函数中初始化所有变量。

ex.前任。

class FooState extends State<Foo> { 
    int someVariable;

    @override
    void initState() {
        someVariable = 0;
    }
}

You need to have all of your variables assigned a value in the initState() function in order for this to work.您需要在initState()函数中为所有变量分配一个值才能使其正常工作。

For more info check out the docs at: https://api.flutter.dev/flutter/widgets/State/initState.html有关更多信息,请查看以下文档: https : //api.flutter.dev/flutter/widgets/State/initState.html

There are a couple of age-old design patterns that might be useful in this situation.在这种情况下,有几种古老的设计模式可能很有用。 Having a reset option is cool, but what's cooler is undo .有一个重置选项很酷,但更酷的是undo

See how the Command and Memento patterns can be implemented in Flutter with these tutorials: Command |通过以下教程了解如何在 Flutter 中实现命令备忘录模式: 命令| Memento 纪念

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM