当键盘出现时,我遇到了重建小部件的问题。我尝试使用 sizer 包,但永远无法弄清楚如何让它工作,当我从这个屏幕返回时,前一个屏幕中的所有内容都将重建,请注意:如果我不单击键盘,则typeaheadwidget
键盘不会单击t 显示状态保留在前一个屏幕中,但一旦键盘弹出,小部件就会重建,您可以检查一下吗?
class SearchScreen extends StatefulWidget {
@override
_SearchScreenState createState() => _SearchScreenState();
}
class _SearchScreenState extends State<SearchScreen> {
TextEditingController pickUpTextEditingController = TextEditingController();
TextEditingController dropOffTextEditingController = TextEditingController();
@override
void initState() {
super.initState();
}
@override
@mustCallSuper
Widget build(BuildContext context) {
String placeAddress =
Provider.of<AppData>(context).pickUpLocation.placeName ?? "";
pickUpTextEditingController.text = placeAddress;
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
children: [
Container(
height: 250.0,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.black,
blurRadius: 6.0,
spreadRadius: 0.5,
offset: Offset(0.7, 0.7),
)
],
),
child: Padding(
padding: EdgeInsets.only(
left: 25.0, top: 30.0, right: 25.0, bottom: 20.0),
child: Column(
children: [
SizedBox(height: 5.0),
Stack(
children: [
GestureDetector(
onTap: () {
Navigator.pop(
//send back data
context,
dropOffTextEditingController.text);
},
child: Icon(Icons.arrow_back)),
Center(
child: Text(
"Set Drop Off",
style: TextStyle(
fontSize: 18.0, fontFamily: "Brand-Bold"),
),
)
],
),
SizedBox(height: 16.0),
Row(
children: [
Image.asset("images/images/pickicon.png",
height: 16.0, width: 16.0),
SizedBox(width: 18.0),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius: BorderRadius.circular(5.0),
),
child: Padding(
padding: EdgeInsets.all(3.0),
child: TextField(
controller: pickUpTextEditingController,
decoration: InputDecoration(
hintText: "PickUp Location",
fillColor: Colors.grey[400],
filled: true,
border: InputBorder.none,
isDense: true,
contentPadding: EdgeInsets.only(
left: 11.0, top: 8.0, bottom: 8.0),
),
),
),
))
],
),
SizedBox(height: 10.0),
Row(
children: [
Image.asset("images/images/desticon.png",
height: 16.0, width: 16.0),
SizedBox(width: 18.0),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.grey[400],
borderRadius: BorderRadius.circular(5.0),
),
child: Padding(
padding: EdgeInsets.all(3.0),
child: TypeAheadField(
itemBuilder: null,
onSuggestionSelected: null,
suggestionsCallback: null,
),
),
),
),
],
),
],
),
),
),
],
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 19
这是键盘弹出后小部件被重建的唯一原因。您的一个或多个小部件的大小取决于 MediaQuery。
您可以尝试从 LayoutBuilder 获取屏幕尺寸作为 MediaQuery 的替代方案。
您不应该尝试控制何时build
调用该方法。build
Flutter 将在决定需要时调用(例如键盘出现、设备旋转、父级重建等)。
相反,您应该确保您的构建方法是“纯”函数。具体来说,在 Flutter 中,这意味着您不应执行任何具有“副作用”的操作(基本上是修改应用程序状态的任何操作)。
例如:
Widget build(BuildContext context) {
final x = 2 + 3; // fine, nothing else is modified
final state = context.watch<MyModel>(); // also fine, only reading data
controller.text = "hello"; // BAD, modifies the state of the app
return ...;
}
Run Code Online (Sandbox Code Playgroud)
相反,您应该将具有副作用的逻辑移至其他生命周期方法(例如initState()
,didChangeDepencencies()
等)。
例如,如果您想在文本字段首次出现时将其设置为特定字符串,则可以使用initState
:
class _SearchScreenState extends State<SearchScreen> {
@override
void initState() {
super.initState();
final data = context.read<AppData>();
controller.text = data.pickUpLocation.placeName ?? "";
}
Widget build(BuildContext context) {
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
现在build()
可以在需要时调用,而无需重置文本字段的状态。
请注意,即使有某种方法可以阻止您的小部件被重建,这也可能不是您想要的,因为 UI 不会更新以适应键盘。
归档时间: |
|
查看次数: |
11724 次 |
最近记录: |