StatefulWidget 页面在键盘打开时重新创建
Posted
技术标签:
【中文标题】StatefulWidget 页面在键盘打开时重新创建【英文标题】:StatefulWidget Page recreate when keyboard is open 【发布时间】:2019-05-24 00:19:33 【问题描述】:在我的个人资料页面中有编辑选项,当使用单击编辑图标时,我使用布尔条件将 Text 小部件更改为 TextField 小部件,例如widget.isUpdate ? new Flexible(child: new TextField()) : Text("Text Widget")
它可以工作,但是当 TextField 聚焦时,键盘在那个时候打开 StatefulWidget 再次重新创建 Boolean变为 false 然后 Textfield 移动到 Text Widget。这种情况只发生在页面有导航器推送页面(第二页)之类的时候
Navigator.push(context,MaterialPageRoute(builder: (context) => UpdateProfile()))
如果此页面作为默认主页,则可以正常工作。我不知道我犯了什么错误。
代码:
import 'package:flutter/material.dart';
class UpdateProfile extends StatefulWidget
bool isUpdate = false;
@override
State<StatefulWidget> createState()
// TODO: implement createState
return UpdateProfileState();
class UpdateProfileState extends State<UpdateProfile>
@override
Widget build(BuildContext context)
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Update"),
elevation: 2.0),
body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.red,
margin: const EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
widget.isUpdate ? new Flexible(child: new TextField()) : Text("Text Widget"),
GestureDetector(
child: IconTheme(
data: IconThemeData(color: Color(0xFFffffff)),
child: Icon(Icons.edit)),
onTap: ()
setState(()
widget.isUpdate = !widget.isUpdate;
);
,
)
],
),
),
);
问题:
如果我设置为主页,则可以正常工作,如下所示
import 'package:expense_manager_app/page/splash_page.dart';
import 'package:expense_manager_app/page/update_profile.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
brightness: Brightness.dark,
primaryColor: Colors.red[500],
accentColor: Colors.green[900],
),
home: UpdateProfile(),
);
【问题讨论】:
如果有人否决了这个问题,请说明原因 【参考方案1】:您应该将变量 isUpdate
移动到您的状态中,记住小部件是不可变的。
class UpdateProfileState extends State<UpdateProfile>
bool isUpdate = false;
@override
Widget build(BuildContext context)
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text("Update"),
elevation: 2.0),
body: Container(
width: double.infinity,
height: double.infinity,
color: Colors.red,
margin: const EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
isUpdate ? new Flexible(child: new TextField()) : Text("Text Widget"),
GestureDetector(
child: IconTheme(
data: IconThemeData(color: Color(0xFFffffff)),
child: Icon(Icons.edit)),
onTap: ()
setState(()
isUpdate = !isUpdate;
);
,
)
],
),
),
);
并且还要改变这个:
Navigator.push(context,MaterialPageRoute(builder: (context) => UpdateProfile()))
到这里:
final page = UpdateProfile();
Navigator.push(context,MaterialPageRoute(builder: (context) => page ))
【讨论】:
是的,我已经厌倦了它的工作,但是为什么当这个页面像导航器推送一样作为第二页时它不能工作。它是如何作为主页默认页面工作的。 你有没有像我上面写的那样改变推送? 设置为 final 后它的工作所以我怀疑我是否直接在 MaterialPageRoute 中提到然后每次重新创建对象? 是的,构建器中的所有内容都已重新创建,因此您必须将小部件提取到变量中【参考方案2】:这是因为你设置了默认 bool isUpdate = false;
将其更改为
bool isUpdate;
并使用 State 类的initState
方法并将isUpdate
设置为false。我会被叫一次。
@override
void initState()
widget.isUpdate = false;
super.initState();
【讨论】:
如果我在 initState 中设置的不是默认值,那么它会抛出错误 boolean expression must not be null @MageshPandian 然后将 bool isUpdate; 放入您的状态类中,然后删除 initState 方法中的 widget 前缀。 是的,它已经工作了,但我怀疑为什么它在键盘打开期间重新创建或重新初始化,当页面作为第二页而不是主页时【参考方案3】:另外,如果你在 didChangeDependencies 方法上做一些事情,那也会导致
【讨论】:
以上是关于StatefulWidget 页面在键盘打开时重新创建的主要内容,如果未能解决你的问题,请参考以下文章
从 iPhone 主屏幕重新打开时,如何在 jQuery Mobile 应用程序上缓存并保留上次访问的页面?