TextEditingController makes widget lose its previous state
When I use TextEditingController
in CupertinoTextField
, and change to another widget(page) and return, the previous state in that page is lost.
When I uncomment //controller: textController,
everything works fine.
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);
})
);
}
}
The expected result(without controller set):get back and the state keeps the same.
Actual results(with controller set): get back and the state lost


add a comment |
When I use TextEditingController
in CupertinoTextField
, and change to another widget(page) and return, the previous state in that page is lost.
When I uncomment //controller: textController,
everything works fine.
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);
})
);
}
}
The expected result(without controller set):get back and the state keeps the same.
Actual results(with controller set): get back and the state lost


@JeromeEscalante I have tried to removetextController.dispose();
, and it's still not working.
– user6456568
Jan 1 at 14:40
It's weird for me that it even works, since I thought bottomnav recreates a new navigation on entering a tabbar.
– Syph
Jan 1 at 14:56
@Syph Sorry, I don't quite understand, do you have a better implementation?
– user6456568
Jan 1 at 14:59
1
No, I thought the default behaviour was like your second example. Your state lies within your navigator, however in each tab lies a separate navigator. Your navigator will remember the stack of your views, but when you try to go to a different tab, it disposes your current tab.
– Syph
Jan 1 at 15:23
@Syph wired thing is that in my first example,Search
is not disposed, while in second example,Search
is disposed in Widget3
– user6456568
Jan 1 at 15:51
add a comment |
When I use TextEditingController
in CupertinoTextField
, and change to another widget(page) and return, the previous state in that page is lost.
When I uncomment //controller: textController,
everything works fine.
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);
})
);
}
}
The expected result(without controller set):get back and the state keeps the same.
Actual results(with controller set): get back and the state lost


When I use TextEditingController
in CupertinoTextField
, and change to another widget(page) and return, the previous state in that page is lost.
When I uncomment //controller: textController,
everything works fine.
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);
})
);
}
}
The expected result(without controller set):get back and the state keeps the same.
Actual results(with controller set): get back and the state lost




edited Jan 2 at 0:03
dope_vector
198111
198111
asked Jan 1 at 14:31
user6456568user6456568
11019
11019
@JeromeEscalante I have tried to removetextController.dispose();
, and it's still not working.
– user6456568
Jan 1 at 14:40
It's weird for me that it even works, since I thought bottomnav recreates a new navigation on entering a tabbar.
– Syph
Jan 1 at 14:56
@Syph Sorry, I don't quite understand, do you have a better implementation?
– user6456568
Jan 1 at 14:59
1
No, I thought the default behaviour was like your second example. Your state lies within your navigator, however in each tab lies a separate navigator. Your navigator will remember the stack of your views, but when you try to go to a different tab, it disposes your current tab.
– Syph
Jan 1 at 15:23
@Syph wired thing is that in my first example,Search
is not disposed, while in second example,Search
is disposed in Widget3
– user6456568
Jan 1 at 15:51
add a comment |
@JeromeEscalante I have tried to removetextController.dispose();
, and it's still not working.
– user6456568
Jan 1 at 14:40
It's weird for me that it even works, since I thought bottomnav recreates a new navigation on entering a tabbar.
– Syph
Jan 1 at 14:56
@Syph Sorry, I don't quite understand, do you have a better implementation?
– user6456568
Jan 1 at 14:59
1
No, I thought the default behaviour was like your second example. Your state lies within your navigator, however in each tab lies a separate navigator. Your navigator will remember the stack of your views, but when you try to go to a different tab, it disposes your current tab.
– Syph
Jan 1 at 15:23
@Syph wired thing is that in my first example,Search
is not disposed, while in second example,Search
is disposed in Widget3
– user6456568
Jan 1 at 15:51
@JeromeEscalante I have tried to remove
textController.dispose();
, and it's still not working.– user6456568
Jan 1 at 14:40
@JeromeEscalante I have tried to remove
textController.dispose();
, and it's still not working.– user6456568
Jan 1 at 14:40
It's weird for me that it even works, since I thought bottomnav recreates a new navigation on entering a tabbar.
– Syph
Jan 1 at 14:56
It's weird for me that it even works, since I thought bottomnav recreates a new navigation on entering a tabbar.
– Syph
Jan 1 at 14:56
@Syph Sorry, I don't quite understand, do you have a better implementation?
– user6456568
Jan 1 at 14:59
@Syph Sorry, I don't quite understand, do you have a better implementation?
– user6456568
Jan 1 at 14:59
1
1
No, I thought the default behaviour was like your second example. Your state lies within your navigator, however in each tab lies a separate navigator. Your navigator will remember the stack of your views, but when you try to go to a different tab, it disposes your current tab.
– Syph
Jan 1 at 15:23
No, I thought the default behaviour was like your second example. Your state lies within your navigator, however in each tab lies a separate navigator. Your navigator will remember the stack of your views, but when you try to go to a different tab, it disposes your current tab.
– Syph
Jan 1 at 15:23
@Syph wired thing is that in my first example,
Search
is not disposed, while in second example, Search
is disposed in Widget 3
– user6456568
Jan 1 at 15:51
@Syph wired thing is that in my first example,
Search
is not disposed, while in second example, Search
is disposed in Widget 3
– user6456568
Jan 1 at 15:51
add a comment |
1 Answer
1
active
oldest
votes
The explanation for the observed behavior is the following:
CupertinoTextField
uses an internal TextEditingController
for which the framework automatically sets an AutomaticKeepAlive
. This keepAlive is responsible for keeping the state.
If you use your own controller, you are in charge of attaching the AutomaticKeepAlive
because the framework doesn't do it for you.
The following snippet adds the keepAlive to your code:
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;
}
In MaterialApp its happening the opposite. When i pop the screen out and visit again the TextField has the previous text. How can I remove that ?
– XoXo
Jan 5 at 20:20
How are you creating the page? Some code would help. Maybe in another question.
– chemamolins
Jan 5 at 23:50
Here is the link to the question: stackoverflow.com/q/54055993/8327394
– XoXo
Jan 6 at 5:40
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53996291%2ftexteditingcontroller-makes-widget-lose-its-previous-state%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
The explanation for the observed behavior is the following:
CupertinoTextField
uses an internal TextEditingController
for which the framework automatically sets an AutomaticKeepAlive
. This keepAlive is responsible for keeping the state.
If you use your own controller, you are in charge of attaching the AutomaticKeepAlive
because the framework doesn't do it for you.
The following snippet adds the keepAlive to your code:
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;
}
In MaterialApp its happening the opposite. When i pop the screen out and visit again the TextField has the previous text. How can I remove that ?
– XoXo
Jan 5 at 20:20
How are you creating the page? Some code would help. Maybe in another question.
– chemamolins
Jan 5 at 23:50
Here is the link to the question: stackoverflow.com/q/54055993/8327394
– XoXo
Jan 6 at 5:40
add a comment |
The explanation for the observed behavior is the following:
CupertinoTextField
uses an internal TextEditingController
for which the framework automatically sets an AutomaticKeepAlive
. This keepAlive is responsible for keeping the state.
If you use your own controller, you are in charge of attaching the AutomaticKeepAlive
because the framework doesn't do it for you.
The following snippet adds the keepAlive to your code:
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;
}
In MaterialApp its happening the opposite. When i pop the screen out and visit again the TextField has the previous text. How can I remove that ?
– XoXo
Jan 5 at 20:20
How are you creating the page? Some code would help. Maybe in another question.
– chemamolins
Jan 5 at 23:50
Here is the link to the question: stackoverflow.com/q/54055993/8327394
– XoXo
Jan 6 at 5:40
add a comment |
The explanation for the observed behavior is the following:
CupertinoTextField
uses an internal TextEditingController
for which the framework automatically sets an AutomaticKeepAlive
. This keepAlive is responsible for keeping the state.
If you use your own controller, you are in charge of attaching the AutomaticKeepAlive
because the framework doesn't do it for you.
The following snippet adds the keepAlive to your code:
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;
}
The explanation for the observed behavior is the following:
CupertinoTextField
uses an internal TextEditingController
for which the framework automatically sets an AutomaticKeepAlive
. This keepAlive is responsible for keeping the state.
If you use your own controller, you are in charge of attaching the AutomaticKeepAlive
because the framework doesn't do it for you.
The following snippet adds the keepAlive to your code:
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;
}
answered Jan 1 at 16:30


chemamolinschemamolins
2,86411018
2,86411018
In MaterialApp its happening the opposite. When i pop the screen out and visit again the TextField has the previous text. How can I remove that ?
– XoXo
Jan 5 at 20:20
How are you creating the page? Some code would help. Maybe in another question.
– chemamolins
Jan 5 at 23:50
Here is the link to the question: stackoverflow.com/q/54055993/8327394
– XoXo
Jan 6 at 5:40
add a comment |
In MaterialApp its happening the opposite. When i pop the screen out and visit again the TextField has the previous text. How can I remove that ?
– XoXo
Jan 5 at 20:20
How are you creating the page? Some code would help. Maybe in another question.
– chemamolins
Jan 5 at 23:50
Here is the link to the question: stackoverflow.com/q/54055993/8327394
– XoXo
Jan 6 at 5:40
In MaterialApp its happening the opposite. When i pop the screen out and visit again the TextField has the previous text. How can I remove that ?
– XoXo
Jan 5 at 20:20
In MaterialApp its happening the opposite. When i pop the screen out and visit again the TextField has the previous text. How can I remove that ?
– XoXo
Jan 5 at 20:20
How are you creating the page? Some code would help. Maybe in another question.
– chemamolins
Jan 5 at 23:50
How are you creating the page? Some code would help. Maybe in another question.
– chemamolins
Jan 5 at 23:50
Here is the link to the question: stackoverflow.com/q/54055993/8327394
– XoXo
Jan 6 at 5:40
Here is the link to the question: stackoverflow.com/q/54055993/8327394
– XoXo
Jan 6 at 5:40
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53996291%2ftexteditingcontroller-makes-widget-lose-its-previous-state%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
@JeromeEscalante I have tried to remove
textController.dispose();
, and it's still not working.– user6456568
Jan 1 at 14:40
It's weird for me that it even works, since I thought bottomnav recreates a new navigation on entering a tabbar.
– Syph
Jan 1 at 14:56
@Syph Sorry, I don't quite understand, do you have a better implementation?
– user6456568
Jan 1 at 14:59
1
No, I thought the default behaviour was like your second example. Your state lies within your navigator, however in each tab lies a separate navigator. Your navigator will remember the stack of your views, but when you try to go to a different tab, it disposes your current tab.
– Syph
Jan 1 at 15:23
@Syph wired thing is that in my first example,
Search
is not disposed, while in second example,Search
is disposed in Widget3
– user6456568
Jan 1 at 15:51