重现步骤
- 按 操作 按钮。
- 检查
_widgetKey.currentState
在actionHandler
中。
预期结果
_widgetKey
应具有有效的 currentState
, currentWidget
值
实际结果
_widgetKey
对于 currentState
、 currentWidget
和其他字段具有空值
代码示例
代码示例
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyPage extends StatefulWidget {
const MyPage({super.key});
@override
MyPageState createState() => MyPageState();
}
class MyPageState extends State<MyPage> {
ListBody _widgets = const ListBody();
final GlobalKey _widgetKey = GlobalKey();
Widget inputWidget = const TextField();
@override
void initState() {
setState(() {
inputWidget = TextField(key: _widgetKey);
_widgets = widgets(context);
});
super.initState();
}
@override
Widget build(BuildContext context) {
var widget = Scaffold(
body: ListView(
children: [
inputWidget,
const Text("Widgets"),
_widgets,
TextButton(onPressed: actionHandler, child: const Text("Action")),
],
),
);
return widget;
}
void actionHandler() async {
if (_widgetKey.currentState == null) {
debugPrint("state is null");
}
}
ListBody widgets(BuildContext context) {
return ListBody(
children: List.generate(18, (index) {
return const TextField();
}));
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: const Center(child: MyPage()),
);
}
}
截图或视频
截图/视频演示
[上传媒体在这里]
日志
日志
[Paste your logs here]
Flutter Doctor 输出
Doctor 输出
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.22.2, on Microsoft Windows [Version 10.0.22631.3880], locale uk-UA)
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.8.3)
[√] Android Studio (version 2021.2)
[√] IntelliJ IDEA Community Edition (version 2023.1)
[√] VS Code (version 1.91.1)
[√] Connected device (3 available)
[√] Network resources
• No issues found!
5条答案
按热度按时间mftmpeh81#
请注意,如果
widgets
方法生成的子部件少于18个,则一切正常。cdmah0mi2#
感谢您的报告@pic16f887
您能检查https://stackoverflow.com/questions/75274817/global-key-is-not-restoring-state-sometimes-of-child-widget并看看它是否对您的情况有所帮助吗?
mrzz3bfm3#
@darshankawar I am not sure that these issues are the same as I am passing
_widgetKey
to theTextField(key: _widgetKey)
only once. And even when I pass key in build method the result is the same.The problem is reproduced only when
ListView
contains less than some number of widgets (in my case if widgets generates more 18 widgets) everything works as expected. When I replacingListView
forSingleChildScrollView
and Column as a Child the problem is gone.5n0oy7gb4#
感谢您的更新。我认为它在少于18个小部件的情况下可以正常工作,因为它可以渲染屏幕上的所有可用内容。对于18个,其中一些元素不在屏幕上,所以它们可能不会被计算。您可以尝试使用
ListView.builder
来通过索引获取项目,也可以尝试传递reverse: true
来按需访问子项。aiqt4smr5#
我认为在小于18个小部件的情况下,它可以正常工作,因为它可以渲染屏幕上的所有可用元素。对于18个,其中一些元素不在屏幕上,所以它们可能不会被计算。你可以尝试使用ListView.builder通过索引获取项目,也可以尝试传递reverse:true以按需访问子项。
@darshankawar 当我添加了除了
inputWidget
和Text
之外的17个小部件以及具有globalKey
的inputWidget
和Text
时,有些元素不在屏幕上,但我没有观察到这个问题。ListView.builder没有解决这个问题。