如何使用 GlobalKey 来保持小部件的状态

tha*_*h84 5 flutter

我想在父级GlobalKey状态更改后保留子级小部件状态。有一种解决方法可以通过使用来Opacity解决问题,但我想知道为什么GlobalKey在这种情况下不能按预期工作。

import 'dart:async';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Retrieve Text Input',
      home: MainScreen(),
    );
  }
}

class MainScreen extends StatefulWidget {
  @override
  _MainScreenState createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  final _key = GlobalKey();
  bool _showTimer = true;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Title'),
          centerTitle: false,
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              TextButton(
                  onPressed: () => setState(() {
                        _showTimer = !_showTimer;
                      }),
                  child: Text('show/hide')),
              _showTimer ? TimerWidget(key: _key) : Container()
            ],
          ),
        ));
  }
}

class TimerWidget extends StatefulWidget {
  const TimerWidget({Key key}) : super(key: key);

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

const int TIME_REMINDING_SECONDS = 480;

class _TimerWidgetState extends State<TimerWidget> {
  Timer _timer;
  int _start = TIME_REMINDING_SECONDS;

  @override
  Widget build(BuildContext context) {
    return Text(
        '${(_start ~/ 60).toString().padLeft(2, '0')}:${(_start % 60).toString().padLeft(2, '0')}',
        style: TextStyle(
            color: _start > 10 ? Colors.amber : Colors.red, fontSize: 20));
  }

  @override
  initState() {
    super.initState();
    _startTimer();
  }

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

  _startTimer() {
    const oneSec = const Duration(seconds: 1);
    _timer = new Timer.periodic(
      oneSec,
      (Timer timer) => setState(
        () {
          if (_start < 1) {
            timer.cancel();
          } else {
            _start = _start - 1;
          }
        },
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

每次父级状态更改时,您都会看到计时器重新启动到初始值。我尝试了这里的解决方案,但没有成功。

Nag*_*ual 2

作为一个选项,您可以跳过GlobalKey并简单使用Offstage小部件

Offstage(offstage: !_showTimer, child: TimerWidget()),
Run Code Online (Sandbox Code Playgroud)

另一个答案提到了Visibility参数maintainState
这是毫无意义的,因为它Offstage在幕后使用。