TextEditingController makes widget lose its previous state












1















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.



expected



Actual results(with controller set): get back and the state lost



actual










share|improve this question

























  • @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 Widget 3

    – user6456568
    Jan 1 at 15:51
















1















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.



expected



Actual results(with controller set): get back and the state lost



actual










share|improve this question

























  • @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 Widget 3

    – user6456568
    Jan 1 at 15:51














1












1








1








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.



expected



Actual results(with controller set): get back and the state lost



actual










share|improve this question
















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.



expected



Actual results(with controller set): get back and the state lost



actual







android ios dart flutter






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 0:03









dope_vector

198111




198111










asked Jan 1 at 14:31









user6456568user6456568

11019




11019













  • @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 Widget 3

    – 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











  • 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 Widget 3

    – 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












1 Answer
1






active

oldest

votes


















1














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;
}





share|improve this answer
























  • 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











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
});


}
});














draft saved

draft discarded


















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









1














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;
}





share|improve this answer
























  • 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
















1














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;
}





share|improve this answer
























  • 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














1












1








1







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;
}





share|improve this answer













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;
}






share|improve this answer












share|improve this answer



share|improve this answer










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



















  • 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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith