Mahesh Jamdade
Mahesh Jamdade

Reputation: 20231

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

Let's say I have a few sliders and switches on my page, I change their state and modify them, I understand that we do setState to show the changed state of the widget tree and rebuild it, but I would like to know if there's a way to undo all those changes and go back to the initial state (state the app was when it was first built)? I don't want to call a custom function which manually resets the variables to initial values. Nor the routes should be removed and added back (because it would show the transition)

Upvotes: 10

Views: 35293

Answers (7)

CopsOnRoad
CopsOnRoad

Reputation: 267554

If you want to do things out of the box

enter image description here


Short answer:

Use any of the below:

Navigator.pushReplacementNamed(context, '/currentRoute');
Navigator.popAndPushNamed(context, '/currentRoute');

Long answer:

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),
          ),
          TextButton(
            onPressed: _reset,
            child: Text('RESET'),
          ),
        ],
      ),
    );
  }
}

A better approach might be with keys. Here's the key approach

Upvotes: 21

CopsOnRoad
CopsOnRoad

Reputation: 267554

Screenshot:

enter image description here


Using key to change the state.

import 'package:flutter/material.dart';
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(),
            ElevatedButton(
              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),
        ),
      ],
    );
  }
}

Upvotes: 6

Mircea Dragota
Mircea Dragota

Reputation: 754

A simple trick would be to pop and push with the same route. Like this:

Navigator.popAndPushNamed(context, "same_route");

Upvotes: 9

Julian H
Julian H

Reputation: 1859

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.

See how the Command and Memento patterns can be implemented in Flutter with these tutorials: Command | Memento

Upvotes: 2

CopsOnRoad
CopsOnRoad

Reputation: 267554

Screenshot:

enter image description here

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'),
            ),
          ],
        ),
      ),
    );
  }
}

Upvotes: 1

PossiblyAShrub
PossiblyAShrub

Reputation: 587

You can call YourStateClass.initState() to revert to its original initialized state.

Also make sure that when you construct your state, you will want to initialize all of your variables in the void initState() function.

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.

For more info check out the docs at: https://api.flutter.dev/flutter/widgets/State/initState.html

Upvotes: 0

HasanAlyazidi
HasanAlyazidi

Reputation: 619

Here is one way of many to reset to the initial data

enter image description here

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'),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

Upvotes: 1

Related Questions