#flutter #layout #key
#flutter #макет #Клавиша
Вопрос:
Я пытаюсь получить размер контейнера с помощью функции, которая обычно работает. Теперь он терпит неудачу в соответствии с отладчиком, потому что он не может найти ключ контейнера в дереве виджетов. Ошибка заключается в том, что метод ‘findRenderObject’ был вызван в null. Получатель: null Я вижу ключ, getSize()
но при переходе в строку с ошибкой я нахожу объяснение, что он не может найти виджет, если возвращается значение null. Есть идеи, почему это так?
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
GlobalKey _keyScreenContainer = GlobalKey(); // <-------- key declared
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
key: _keyScreenContainer, // <--------- key allocated
width: 20, height: 20,
child: Text("${getSize(_keyScreenContainer, context)}"),
)
);
}
Size getSize(GlobalKey _key, BuildContext context) {
final RenderBox renderBox = _key.currentContext.findRenderObject(); // <---- error
final boxSize = renderBox.size;
print (boxSize);
return boxSize;
}
}
Комментарии:
1. Я не уверен, но можете ли вы попробовать свой ключ без подчеркивания (_): keyScreenContainer и getSize(ключ GlobalKey, …
Ответ №1:
Ошибка заключается в том, что вы вызываете функцию getSize еще до завершения сборки. Вы можете вызвать функцию после завершения компоновки виджета либо в initState с помощью WidgetsBinding.instance .addPostFrameCallback((_) => someFunction()), либо с помощью чего-то вроде кнопки. Пожалуйста, смотрите код ниже :
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
GlobalKey _keyScreenContainer = GlobalKey();
@override
void initState(){
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => print("${getSize(_keyScreenContainer, context)}"));
}
@override
Widget build(BuildContext context) {
return Column(children: [
Container(
key: _keyScreenContainer,
width: 20, height: 20,
child: Text("abc"),
), RaisedButton(onPressed:(){
print("${getSize(_keyScreenContainer, context)}");
},child:Text("Get size"))]);
}
Size getSize(GlobalKey key, BuildContext context) {
final RenderBox renderBox = key.currentContext.findRenderObject(); // <---- error
final boxSize = renderBox.size;
print (boxSize);
return boxSize;
}
}
Комментарии:
1. Это, безусловно, имеет смысл. Мне было интересно, почему getSize работает на другой странице, но теперь, снова взглянув на нее, я понимаю, что она вызывается там только после нажатия кнопки. Приветствия!