在 null 上调用了方法“[]”。接收者:null 尝试调用:[](0) !我在这里做错了什么?
The method '[]' was called on null. Receiver: null Tried calling: [](0) ! What am I doing Wrong here?
════════ Exception caught by widgets library
═══════════════════════════════════ The following NoSuchMethodError
was thrown building: The method '[]' was called on null. Receiver:
null Tried calling:
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeScreen(title: 'Email Client App'),
);
}
}
home_screen.dart
class HomeScreen extends StatelessWidget {
HomeScreen({this.title});
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: MessagesScreen());
}
}
message_screen.dart
import 'dart:convert';
import 'package:email_client_app/models/message.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MessagesScreen extends StatefulWidget {
@override
_MessagesScreenState createState() => _MessagesScreenState();
}
class _MessagesScreenState extends State<MessagesScreen> {
Future loadMessageFromAsset() async {
await Future.delayed(Duration(seconds: 2));
return await rootBundle.loadString("data/message.json");
}
Future<List<Message>> getMessagesFromAsset() async {
String jsonString = await loadMessageFromAsset();
List<dynamic> data = json.decode(jsonString);
List<Message> messages =
data.map((data) => Message.fromJson(data)).toList();
return messages;
}
@override
void initState() {
getMessagesFromAsset();
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: getMessagesFromAsset(),
builder: (context, messages) {
List<Message> messageList = messages.data;
return ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
** 这是错误所在!**
var message = messageList[index];
--
return ListTile(
isThreeLine: true,
leading: CircleAvatar(child: Text('ND')),
title: Text(messageList[index].title),
subtitle: Text(
message.body,
maxLines: 2,
),
trailing: Icon(
Icons.more_horiz_outlined,
color: Colors.blueAccent,
),
);
},
);
});
}
}
message.dart(消息模型class)。 # 从 message.json
检索本地数据源
class Message {
Message({this.title, this.body});
String title, body;
factory Message.fromJson(Map<String, dynamic> data) {
return Message(title: data['title'], body: data['body']);
}
Map<String, dynamic> toJson() {
return {'title': title, 'body': body};
}
}
message.json
[
{
"title": "Title 1",
"body": "Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consectetur adipisci elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua."
},
{
"title": "Title 2",
"body": "Lorem ipsum dolor sit amet. "
}
]
Return 指示符或连接状态等待时的任何内容。
return FutureBuilder(
future: getMessagesFromAsset(),
builder: (context, messages) {
// add this one
if (messages.connectionState == ConnectionState.waiting) {
return Text("Loading...");
}
List<Message> messageList = messages.data;
return ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return ListTile(
isThreeLine: true,
leading: CircleAvatar(child: Text('ND')),
title: Text(messageList[index].title),
subtitle: Text(
message.body,
maxLines: 2,
),
trailing: Icon(
Icons.more_horiz_outlined,
color: Colors.blueAccent,
),
);
},
);
});
我认为您做错了几件事。
您在两个地方调用方法 getMessagesFromAsset
:initState
和 FutureBuilder
。从 initState
.
中移除
您的方法 getMessageskFromAsset
可能需要在映射方法中使用不同的变量名称:
Future<List<Message>> getMessagesFromAsset() async {
String jsonString = await loadMessageFromAsset();
List<dynamic> data = json.decode(jsonString);
List<Message> messages =
data.map((messageData) => Message.fromJson(messageData)).toList(); // here
return messages;
}
检查messages
列表是否为null
。
List<Message> messageList = messages.data ?? [];
里面ListView.builder
,你用的是固定值5
,会导致索引越界异常
return ListView.builder(
itemCount: messages?.length ?? 0, // Use messages.length instead of `5`
════════ Exception caught by widgets library ═══════════════════════════════════ The following NoSuchMethodError was thrown building: The method '[]' was called on null. Receiver: null Tried calling:
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeScreen(title: 'Email Client App'),
);
}
}
home_screen.dart
class HomeScreen extends StatelessWidget {
HomeScreen({this.title});
final String title;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: MessagesScreen());
}
}
message_screen.dart
import 'dart:convert';
import 'package:email_client_app/models/message.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MessagesScreen extends StatefulWidget {
@override
_MessagesScreenState createState() => _MessagesScreenState();
}
class _MessagesScreenState extends State<MessagesScreen> {
Future loadMessageFromAsset() async {
await Future.delayed(Duration(seconds: 2));
return await rootBundle.loadString("data/message.json");
}
Future<List<Message>> getMessagesFromAsset() async {
String jsonString = await loadMessageFromAsset();
List<dynamic> data = json.decode(jsonString);
List<Message> messages =
data.map((data) => Message.fromJson(data)).toList();
return messages;
}
@override
void initState() {
getMessagesFromAsset();
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: getMessagesFromAsset(),
builder: (context, messages) {
List<Message> messageList = messages.data;
return ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
** 这是错误所在!**
var message = messageList[index];
--
return ListTile(
isThreeLine: true,
leading: CircleAvatar(child: Text('ND')),
title: Text(messageList[index].title),
subtitle: Text(
message.body,
maxLines: 2,
),
trailing: Icon(
Icons.more_horiz_outlined,
color: Colors.blueAccent,
),
);
},
);
});
}
}
message.dart(消息模型class)。 # 从 message.json
检索本地数据源class Message {
Message({this.title, this.body});
String title, body;
factory Message.fromJson(Map<String, dynamic> data) {
return Message(title: data['title'], body: data['body']);
}
Map<String, dynamic> toJson() {
return {'title': title, 'body': body};
}
}
message.json
[
{
"title": "Title 1",
"body": "Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consectetur adipisci elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua."
},
{
"title": "Title 2",
"body": "Lorem ipsum dolor sit amet. "
}
]
Return 指示符或连接状态等待时的任何内容。
return FutureBuilder(
future: getMessagesFromAsset(),
builder: (context, messages) {
// add this one
if (messages.connectionState == ConnectionState.waiting) {
return Text("Loading...");
}
List<Message> messageList = messages.data;
return ListView.builder(
itemCount: 5,
itemBuilder: (context, index) {
return ListTile(
isThreeLine: true,
leading: CircleAvatar(child: Text('ND')),
title: Text(messageList[index].title),
subtitle: Text(
message.body,
maxLines: 2,
),
trailing: Icon(
Icons.more_horiz_outlined,
color: Colors.blueAccent,
),
);
},
);
});
我认为您做错了几件事。
您在两个地方调用方法
中移除getMessagesFromAsset
:initState
和FutureBuilder
。从initState
.您的方法
getMessageskFromAsset
可能需要在映射方法中使用不同的变量名称:Future<List<Message>> getMessagesFromAsset() async { String jsonString = await loadMessageFromAsset(); List<dynamic> data = json.decode(jsonString); List<Message> messages = data.map((messageData) => Message.fromJson(messageData)).toList(); // here return messages; }
检查
messages
列表是否为null
。List<Message> messageList = messages.data ?? [];
里面
ListView.builder
,你用的是固定值5
,会导致索引越界异常return ListView.builder( itemCount: messages?.length ?? 0, // Use messages.length instead of `5`