【问题标题】:Flutter The method '[]' was called on nullFlutter 在 null 上调用了方法 '[]'
【发布时间】:2020-06-14 12:06:04
【问题描述】:

我正在运行我的应用程序并收到错误消息:

“NoSuchMethodError:方法'[]'在null上被调用。接收者:null。尝试调用:。”

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';

import '../model/Lesson.dart';


class MobileModeScreen extends StatefulWidget {

  @override
  _MobileModeScreenState createState() => _MobileModeScreenState();
}


class _MobileModeScreenState extends State<MobileModeScreen> {

  List<Lesson> _lesson;


  @override
  void initState() {
    super.initState();
    Future.delayed(Duration.zero,() {
      getLessonFromJSON(context);
    });
    print("lessonDescription: ${_lesson[0].lessonTitle}");
  }

  Future<List<Lesson>> getLessonFromJSON(BuildContext context) async {
    String jsonString = await DefaultAssetBundle.of(context).loadString("assets/lessons/lessons.json");

    return await Future.delayed(Duration.zero,() {
      List<dynamic> data = jsonDecode(jsonString);
      List<Lesson> lesson = data.map( (f) => Lesson.fromJSON(f) ).toList();
      _lesson = lesson;
      print("lessonDescription: ${_lesson[0].lessonTitle}");
      return _lesson;
    });
  }


  @override
  Widget build(BuildContext context) {

    return Directionality(
      textDirection: TextDirection.rtl,
      child: Scaffold(
        appBar: AppBar(
          title: Container(
            padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
            decoration: BoxDecoration(
              color: Color(0xffFFFFFF),
              border: Border.all(
                color: Color(0xffF5ED02),
                width: 3,
              ),
              borderRadius: BorderRadius.circular(25.0),
            ),
            child: Text("lessonDescription: ${_lesson[0].lessonTitle}",
              style: TextStyle(
                //fontFamily: "Uthmani",
                color: Color(0xff225587),
              ),
            ),
          ),
          centerTitle: true,
          backgroundColor: Color(0xff7F3F96),
        ),

        body: ListView(
          padding: const EdgeInsets.fromLTRB(5, 15, 5, 5),
          children: <Widget>[
          ],
        ),
        backgroundColor: Color(0xffF0E4F2),
      ),
    );
  }
}

当我尝试从 getLessonFromJSON 函数访问值时,我没有收到错误消息,但在函数之外,它根本不起作用。

我得到的错误:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building Builder:
The method '[]' was called on null.
Receiver: null
Tried calling: [](0)

The relevant error-causing widget was: 
  MaterialApp file:///home/hmalabeh/AndroidStudioProjects/Flutter/Bounyan/boynyan_final/lib/main.dart:12:12
When the exception was thrown, this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1      _MobileModeScreenState.initState (package:boynyanfinal/screens/mobile_mode_screen.dart:26:40)
#2      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:4355:58)
#3      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4201:5)
#4      Element.inflateWidget (package:flutter/src/widgets/framework.dart:3194:14)
...

有人可以帮忙吗。

更新: 我希望能够在build 方法中使用我从函数getLessonFromJSON 获得的内容,就像我在AppBar 中提交的Text 中使用的一样

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    将获取数据移动到不同的函数并等待响应:

    @override
    void initState() {
      super.initState();
      load();
    }
    
    void load() async {
      setState(() {
        await getLessonFromJSON(context);
      });
    }
    
    

    还可以在您使用_lesson 的任何地方放置一个加载器,例如在您的应用栏中:

    var text = _lesson == null ? 'Loading...' : 'lessonDescription: ${_lesson[0].lessonTitle}';
    Text(text,
      style: TextStyle(
      //fontFamily: "Uthmani",
        color: Color(0xff225587),
      ),
    )
    
    

    【讨论】:

    • 对不起,我的描述不够清楚,我已经更新了描述。我想做的是能够在build方法中使用我从函数getLessonFromJSON中得到的东西,就像我在AppBar中提交的Text中使用的一样,我已经尝试了你的建议它没有帮助。
    • 为了避免数据加载前崩溃,你需要为你的屏幕添加某种加载器。
    【解决方案2】:

    我在getLessonFromJSON 中添加了setState(),并在我使用来自_lesson 的值的地方添加了一个加载器,正如@Sami 所建议的那样。

    _lesson 不需要初始化。

    @override
      void initState() {
        super.initState();
        getLessonFromJSON(context);
      }
    
      Future<List<Lesson>> getLessonFromJSON(BuildContext context) async {
        String jsonString = await DefaultAssetBundle.of(context).loadString("assets/lessons/lessons.json");
    
        try{
          return await Future.delayed(Duration.zero,() {
            List<dynamic> data = jsonDecode(jsonString);
            List<Lesson> lesson = data.map( (f) => Lesson.fromJSON(f) ).toList();
            setState(() {
              _lesson = List.from(lesson);
            });
            print("[getLessonFromJSON] lessonDescription: ${lesson[0].lessonTitle}");
            return lesson;
          });
        } catch(e){
          print(e);
        }
      }
    

    加载器

    _lessonTitle = _lesson == null ? 'Loading...' : _lesson[0].lessonTitle;
    

    【讨论】:

      【解决方案3】:

      _lesson 为 null,因为它的值仅在 Future.delayed 被解析时分配。

      要解决它,要么将 print("lessonDescription: ${_lesson[0].lessonTitle}"); 移动到 Future 处理程序中(在 getLessonFromJSON(context); 之后),要么完全删除该行,因为据我所知,它仅用于调试目的。

      这应该可行:

        void initState() {
          super.initState();
          Future.delayed(Duration.zero,() {
            getLessonFromJSON(context);
            print("lessonDescription: ${_lesson[0].lessonTitle}");
          });
        }
      

      【讨论】:

      • 对不起,我的描述不够清楚,我已经更新了描述。我想要做的是能够在build方法中使用我从函数getLessonFromJSON中得到的东西,就像我在AppBar中的Text中使用的一样,是的,我正在使用它进行调试.
      【解决方案4】:

      你应该用一个空列表初始化“_lesson” ```列出_lesson = [];``` 然后使用_lesson.add(item) 将项目添加到initState 中的此列表中,并调用setState 以更新应用程序的状态。 这会起作用,但您应该使用 FutureBuilder 进行异步操作,并使用提供程序或块来更好地管理状态

      【讨论】:

      • 返回的数据是List&lt;Lesson&gt;类型,所以使用_lesson.add(item)添加它是行不通的,因为我返回的itemList&lt;Lesson&gt;类型而不是Lesson
      • 所有地图内容完成后,您可以使用 addAll 方法添加到列表中。
      • 这不是一个最佳实践,你应该使用 FutureBuilder 来为 FutureBuilder 提供异步函数作为未来,并根据从未来接收到的数据返回小部件,不要忘记做错误处理如果您不知道如何使用 FutureBuilder 进行操作,请告诉我,我会为您完成此操作
      猜你喜欢
      • 2020-11-06
      • 2019-09-23
      • 2020-06-04
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-03
      • 2021-09-29
      • 2020-04-27
      相关资源
      最近更新 更多