当我在TextEditingController
中使用CupertinoTextField
并切换到另一个小部件(页面)并返回时,该页面中的先前状态会丢失。
取消评论//controller: textController,
时一切正常。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'test',
home: DefaultTabController(
length: 2,
child: Scaffold(
body: TabBarView(
children: [new Search(), new Setting(),
],
),
bottomNavigationBar: Container(
height: 60,
child: new TabBar(
tabs: [
Tab(icon: new Icon(Icons.search)),
Tab(icon: new Icon(Icons.settings)),
],
labelColor: Colors.blue,
unselectedLabelColor: Colors.grey,
),
)
),
),
);
}
}
class Setting extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IconButton(
icon: Icon(Icons.check),
onPressed: () {
Navigator.push(context, CupertinoPageRoute(
builder: (context) =>
new Scaffold(
appBar: AppBar(title: Text('3'),),
)));
});
}
}
class Search extends StatefulWidget {
@override
createState() => new SearchState();
}
class SearchState extends State<Search> {
String currentWord = '';
final TextEditingController textController = new TextEditingController();
@override
void dispose() {
textController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Row(
children: <Widget>[
new Expanded(
child: new CupertinoTextField(
style: TextStyle(color: Colors.white),
cursorColor: Colors.white,
//controller: textController,
maxLines: 1,
clearButtonMode: OverlayVisibilityMode.editing,
onChanged: (text) {
setState(() {
currentWord = text;
});
},
),
),
],
),
),
body: ListView.builder(
itemCount: 5,
itemBuilder: (context, i) {
return Text(currentWord);
})
);
}
}
预期结果(未设置控制器):取回并且状态保持不变。
实际结果(在设置了控制器的情况下):返回并丢失状态
答案 0 :(得分:2)
对观察到的行为的解释如下:
CupertinoTextField
使用内部TextEditingController
,框架会为此内部元素自动设置AutomaticKeepAlive
。该keepAlive负责保持状态。
如果您使用自己的控制器,则因为该框架无法为您完成附加AutomaticKeepAlive
。
以下代码段将keepAlive添加到您的代码中:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'test',
home: DefaultTabController(
length: 2,
child: Scaffold(
body: TabBarView(
children: [
new Search(),
new Setting(),
],
),
bottomNavigationBar: Container(
height: 60,
child: new TabBar(
tabs: [
Tab(icon: new Icon(Icons.search)),
Tab(icon: new Icon(Icons.settings)),
],
labelColor: Colors.blue,
unselectedLabelColor: Colors.grey,
),
)),
),
);
}
}
class Setting extends StatelessWidget {
@override
Widget build(BuildContext context) {
return IconButton(
icon: Icon(Icons.check),
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => new Scaffold(
appBar: AppBar(
title: Text('3'),
),
)));
});
}
}
class Search extends StatefulWidget {
@override
createState() => new SearchState();
}
class SearchState extends State<Search> with AutomaticKeepAliveClientMixin {
String currentWord = '';
final TextEditingController textController = new TextEditingController();
@override
void initState() {
super.initState();
textController?.addListener(updateKeepAlive);
}
@override
void dispose() {
textController?.removeListener(updateKeepAlive);
textController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context); // See AutomaticKeepAliveClientMixin.
return new Scaffold(
appBar: new AppBar(
title: new Row(
children: <Widget>[
new Expanded(
child: new CupertinoTextField(
style: TextStyle(color: Colors.white),
cursorColor: Colors.white,
controller: textController,
maxLines: 1,
clearButtonMode: OverlayVisibilityMode.editing,
onChanged: (text) {
setState(() {
currentWord = text;
});
},
),
),
],
),
),
body: ListView.builder(
itemCount: 5,
itemBuilder: (context, i) {
return Text(currentWord);
}));
}
@override
bool get wantKeepAlive => textController?.text?.isNotEmpty == true;
}