颤振 - 有状态小部件在切换选项卡时不保存计数器状态



我正在学习颤振,我正在使用tabBars,我在保存状态时遇到了问题。 我在下面放了一个我的问题的小工作示例。 基本上,有一个按钮和一个有状态计数器。 当我单击该按钮时,我看到文本字段正确更新。但是,当我切换到其他选项卡并返回时,文本字段恢复为零。

我发现如果我将以下行移到_CounterState之外,使其在文件的顶层定义,那么它就可以正常工作。 当我切换选项卡时,当我切换回来时,计数器保持在正确的计数

int _counter = 0;

我觉得这不是合适的方法,我看到的所有示例在类中都有变量。 谁能给我任何见解? 如果它在类内,为什么它会重置? 我应该把它放在课外吗? 下面是简化的完整示例。

import 'package:flutter/material.dart';
void main() {
runApp(new TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new DefaultTabController(
length: 3,
child: new Scaffold(
appBar: new AppBar(
bottom: new TabBar(
tabs: [
new Tab(icon: new Icon(Icons.directions_car)),
new Tab(icon: new Icon(Icons.directions_transit)),
new Tab(icon: new Icon(Icons.directions_bike)),
],
),
title: new Text('Tabs Demo'),
),
body: new TabBarView(
children: [
new Counter(),
new Icon(Icons.directions_transit),
new Icon(Icons.directions_bike),
],
),
),
),
);
}
}
class Counter extends StatefulWidget {
@override
_CounterState createState() => new _CounterState();
}
class _CounterState extends State<Counter> {
int _counter = 0;
void _increment() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return new Row(
children: <Widget>[
new RaisedButton(
onPressed: _increment,
child: new Text('Increment'),
),
new Text('Count: $_counter'),
],
);
}
}

下面是将计数器移到类外的示例

import 'package:flutter/material.dart';
void main() {
runApp(new TabBarDemo());
}
class TabBarDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new DefaultTabController(
length: 3,
child: new Scaffold(
appBar: new AppBar(
bottom: new TabBar(
tabs: [
new Tab(icon: new Icon(Icons.directions_car)),
new Tab(icon: new Icon(Icons.directions_transit)),
new Tab(icon: new Icon(Icons.directions_bike)),
],
),
title: new Text('Tabs Demo'),
),
body: new TabBarView(
children: [
new Counter(),
new Icon(Icons.directions_transit),
new Icon(Icons.directions_bike),
],
),
),
),
);
}
}
class Counter extends StatefulWidget {
@override
_CounterState createState() => new _CounterState();
}
int _counter = 0; //<-- MOVED OUTSIDE THE _CounterState CLASS
class _CounterState extends State<Counter> {

void _increment() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return new Row(
children: <Widget>[
new RaisedButton(
onPressed: _increment,
child: new Text('Increment'),
),
new Text('Count: $_counter'),
],
);
}
}

由于每次访问给定的 TabView 时都会构建_CounterState小部件,因此您需要将_counter变量放入状态配置类 (Counter(。

class Counter extends StatefulWidget {
int _counter = 0;
@override
_CounterState createState() => new _CounterState();
}
class _CounterState extends State<Counter> {
void _increment() {
setState(() {
widget._counter++;
});
}
@override
Widget build(BuildContext context) {
return new Row(
children: <Widget>[
new RaisedButton(
onPressed: _increment,
child: new Text('Increment'),
),
new Text('Count: ${widget._counter}'),
],
);
}
}

因为我使用了一个解决方案AutomaticKeepAliveClientMixin

你需要将这个mixinStateFullWidget的状态类一起使用。

你需要将true传递给wantKeepAlivegetter 方法。

class SampleWidget extends StatefulWidget {
@override
_SampleWidgetState createState() => _SampleWidgetState();
}
class _SampleWidgetState extends State<SampleWidget> with AutomaticKeepAliveClientMixin{
@override
Widget build(BuildContext context) {
super.build(context);
return Container();
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}

这将保存您的状态并停止您的小部件以再次重新创建。我已经将它与标签栏页面视图一起使用,并且工作正常。

将变量放入该 statefulwidget 中,然后每次都将其调用为 "widget.variable_name">

最新更新