在 null 上调用了方法“[]”。接收者:null 尝试调用:[](0) !我在这里做错了啥? [复制]
Posted
技术标签:
【中文标题】在 null 上调用了方法“[]”。接收者:null 尝试调用:[](0) !我在这里做错了啥? [复制]【英文标题】:The method '[]' was called on null. Receiver: null Tried calling: [](0) ! What am I doing Wrong here? [duplicate]在 null 上调用了方法“[]”。接收者:null 尝试调用:[](0) !我在这里做错了什么? [复制] 【发布时间】:2021-02-28 22:56:55 【问题描述】:════════ 小部件库捕获的异常 ═══════════════════════════════════ 以下NoSuchMethodError 被抛出建筑:方法'[]'在null上被调用。接收者: null 尝试调用:
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(消息模型类)。 # 从 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. "
]
【问题讨论】:
我还想将“loadMessageFromAsset()”和“getMessagesFromAsset()”移动到服务下的不同文件中。在那种情况下,我如何在 message_screen.dart 中获取它的数据? 【参考方案1】:我认为你做错了几件事。
您在两个地方调用方法getMessagesFromAsset
:initState
和FutureBuilder
。从initState
中删除。
您的方法 getMessageskFromAsset
可能需要在 map 方法中使用不同的变量名:
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`
【讨论】:
# itemCount 令人尴尬地错过了。 # 检查消息列表的空值是一个很好的建议。只是澄清一下,connectionState 条件已经在起作用,为什么我们需要检查列表是否为空? 我还想将“loadMessageFromAsset()”和“getMessagesFromAsset()”移动到服务下的不同文件中。在那种情况下,我如何在 message_screen.dart 中获取它的数据? 我在上面的代码中没有看到任何connectionState
条件。不过,如果服务器以空列表响应,您也应该能够处理这种情况。这就是为什么你应该检查列表是否为空并根据它返回适当的小部件。
为了从其他文件中获取message_screen.dart
中的数据,您应该将数据作为参数传递给MessageScreen
小部件。
我使用 CircularProgressiveIndicator 小部件使用 connectionState 更新了我的代码库。还将用于加载和获取数据的功能移至服务。现在可以运行了。【参考方案2】:
连接状态等待时返回指示器或任何东西。
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,
),
);
,
);
);
【讨论】:
以上是关于在 null 上调用了方法“[]”。接收者:null 尝试调用:[](0) !我在这里做错了啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
SharedPreferences 在 null 颤动上调用
如何修复错误:在 null 上调用了 getter 'email'。接收者:空尝试呼叫:电子邮件
NoSuchMethodError(NoSuchMethodError:方法'[]'在null上被调用。接收者:null尝试调用:[](“title”))
尝试在 nul 对象引用上调用虚拟方法 'android.content.ContentResolverr android.id.content.Context.getContentesolver()