我正在使用 Sockets 编写简单的聊天应用程序。当我将主页更改为子页面时,它工作正常,但是当我返回主屏幕并再次进入子页面时,它会显示如下错误:[ERROR:flutter/lib/ui/ui_dart_state.cc(213)] Unhandled Exception: Cannot hit test a render box that has never been laid out. The hitTest() method was called on this RenderBox: RenderErrorBox#b3570 NEEDS-LAYOUT NEEDS-PAINT: creator: ErrorWidget-[#74fe9] ← _BodyBuilder ← MediaQuery ← LayoutId-[<_ScaffoldSlot.body>] ← CustomMultiChildLayout ← AnimatedBuilder ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#ccc61 ink renderer] ← NotificationListener<LayoutChangedNotification> ← PhysicalModel ← AnimatedPhysicalModel ← ⋯ parentData: offset=Offset(0.0, 0.0); id=_ScaffoldSlot.body constraints: MISSING size: MISSING Unfortunately, this object's geometry is not known at this time, probably because it has never been laid out. This means it cannot be accurately hit-tested. If you are trying to perform a hit test during the layout phase itself, make sure you only hit test nodes that have completed layout (e.g. the node's children, after their layout() method has been called). #0 RenderBox.hitTest.<anonymous closure> (package:flutter/src/rendering/box.dart:2380:11)
我不确定它来自哪里。也许它与 Socket 连接有某种连接,我将其作为参数传递给 subPage 的构造函数。我感谢所有帮助,提前致谢! 子页面代码:
import 'dart:typed_data';
import 'package:chat_app/models/ChatUsers.dart';
import 'package:flutter/material.dart';
import 'dart:io';
import 'package:chat_app/globals.dart' as globals;
// Define a custom Form widget.
class RegisterScreen extends StatefulWidget {
late final Socket channel;
RegisterScreen(Socket s) {
this.channel = s;
}
@override
_RegisterScreenState createState() => _RegisterScreenState();
}
class _RegisterScreenState extends State<RegisterScreen> {
List<int> lint = [];
int i=0;
late ChatUsers user;
final TextEditingController _controller = TextEditingController();
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("widget.title"),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Form(
child: TextFormField(
controller: _controller,
decoration: const InputDecoration(labelText: 'Send a message'),
),
),
StreamBuilder(
stream: widget.channel,
builder: (context, snapshot) {
if(snapshot.hasData) {
String decoded = utf8.decode(snapshot.data as Uint8List);
String token = decoded.substring(decoded.indexOf('key')+3,decoded.indexOf('.'));
globals.usersList[i].setToken(token);
print(decoded);
print(token);
i++;
print(globals.usersList);
setState(() {
});
}
return Padding(
padding: const EdgeInsets.symmetric(vertical: 24.0),
child: Text(snapshot.hasData ? snapshot.data.toString() : ''),
);
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: (_sendMessage),
tooltip: 'Send message',
child: const Icon(Icons.send),
),
// This trailing comma makes auto-formatting nicer for build methods.
);
}
void _sendMessage() {
if (_controller.text.isNotEmpty) {
String sender = _controller.text;
String registrationMessage = "{'register':'true', 'sender':'$sender'}";
globals.usersList.add(new ChatUsers(sender));
widget.channel.write(registrationMessage);
}
}
}```
And code of Navigator:
```floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Padding(
padding: const EdgeInsets.all(20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RegisterScreen(widget.sock)));
}, ```