最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

dart - Flutter error - NoSuchMethodErro: '[]' Dynamic call of null Receiver: Instance of 'LinkedSet&

programmeradmin4浏览0评论

I'm studying flutter for a personal project and i'm struggling in this error:

NoSuchMethodErro: '[]'
Dynamic call of null 
Receiver: Instance of 'LinkedSet<Object>'
Arguments [0]

Here is my simple code:

//main.dart
import 'package:flutter/material.dart';
import 'package:mictch_koko_course/pages/home_page.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
      theme: ThemeData(
        primaryColor: Colors.yellow,
      ),
    );
  }
}

//pages/home_page.dart
import 'package:flutter/material.dart';
import 'package:mictch_koko_course/util/todo_tile.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

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

class _HomePageState extends State<HomePage> {

  List toDoList = [
    {"Make Tutorial", false},
    {"Do Exercise", false}
  ];

  void checkBoxChanged(bool? value, int index){
    setState(() {
      toDoList[index][1] = !toDoList[index][1];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.yellow[200],
      appBar: AppBar(
        backgroundColor: Theme.of(context).primaryColor,
        title: Center(child: Text("TO DO")),
        elevation: 0,
      ),
      body: ListView.builder(
        itemCount: toDoList.length,
        itemBuilder: (context, index){
          return TodoTile(
            taskName: toDoList[index][0],
            taskCompleted: toDoList[index][1],
            onChanged: (value) => checkBoxChanged(value, index),
          );
        }
      )
    );
  }
}

//util/todo_tile.dart
import 'package:flutter/material.dart';

class TodoTile extends StatelessWidget {
  final String taskName;
  final bool taskCompleted;
  Function(bool?)? onChanged;

  TodoTile({
    super.key,
    required this.taskName,
    required this.taskCompleted,
    required this.onChanged,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(25.0),
      child: Container(
        padding: EdgeInsets.all(12),
        decoration: BoxDecoration(
          color: Colors.yellow,
          borderRadius: BorderRadius.circular(12),
        ),
        child: Row(
          children: [
            Checkbox(value: taskCompleted, onChanged: onChanged),
            Text(taskName),
          ],
        ),
      ),
    );
  }
}

I tried some fixes with this dynamic onChanged method, but I can't figure out how to fix this error. I also removed every dynamic function to test if this was the problem, but unfortunately, it wasn't.

Any help or tips to how to fix it will be welcome!

I'm studying flutter for a personal project and i'm struggling in this error:

NoSuchMethodErro: '[]'
Dynamic call of null 
Receiver: Instance of 'LinkedSet<Object>'
Arguments [0]

Here is my simple code:

//main.dart
import 'package:flutter/material.dart';
import 'package:mictch_koko_course/pages/home_page.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
      theme: ThemeData(
        primaryColor: Colors.yellow,
      ),
    );
  }
}

//pages/home_page.dart
import 'package:flutter/material.dart';
import 'package:mictch_koko_course/util/todo_tile.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

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

class _HomePageState extends State<HomePage> {

  List toDoList = [
    {"Make Tutorial", false},
    {"Do Exercise", false}
  ];

  void checkBoxChanged(bool? value, int index){
    setState(() {
      toDoList[index][1] = !toDoList[index][1];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.yellow[200],
      appBar: AppBar(
        backgroundColor: Theme.of(context).primaryColor,
        title: Center(child: Text("TO DO")),
        elevation: 0,
      ),
      body: ListView.builder(
        itemCount: toDoList.length,
        itemBuilder: (context, index){
          return TodoTile(
            taskName: toDoList[index][0],
            taskCompleted: toDoList[index][1],
            onChanged: (value) => checkBoxChanged(value, index),
          );
        }
      )
    );
  }
}

//util/todo_tile.dart
import 'package:flutter/material.dart';

class TodoTile extends StatelessWidget {
  final String taskName;
  final bool taskCompleted;
  Function(bool?)? onChanged;

  TodoTile({
    super.key,
    required this.taskName,
    required this.taskCompleted,
    required this.onChanged,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(25.0),
      child: Container(
        padding: EdgeInsets.all(12),
        decoration: BoxDecoration(
          color: Colors.yellow,
          borderRadius: BorderRadius.circular(12),
        ),
        child: Row(
          children: [
            Checkbox(value: taskCompleted, onChanged: onChanged),
            Text(taskName),
          ],
        ),
      ),
    );
  }
}

I tried some fixes with this dynamic onChanged method, but I can't figure out how to fix this error. I also removed every dynamic function to test if this was the problem, but unfortunately, it wasn't.

Any help or tips to how to fix it will be welcome!

Share Improve this question asked Mar 24 at 0:48 Bruno BevilaquaBruno Bevilaqua 33 bronze badges 1
  • It would help if you included the stack trace, or at least point at the line that is throwing the exception. – Randal Schwartz Commented Mar 24 at 0:55
Add a comment  | 

2 Answers 2

Reset to default 0

The issue is that you are treating Map as a list and accessing the values as an index which is not allowed accessing values from the map is done through keys like this:

final taskName = toDoList[0]["task"]; // which will take the name of the first task in the list.
// as you can see the first level is List so we are accessing values using index
// `0` then we have Map and accessing its values through key `task`, `completed`

correct code is:

class _HomePageState extends State<HomePage> {
  List<Map<String, dynamic>> toDoList = [
    {"task": "Make Tutorial", "completed": false},
    {"task": "Do Exercise", "completed": false}
  ];

  void checkBoxChanged(bool? value, int index) {
    setState(() {
      toDoList[index]["completed"] = !toDoList[index]["completed"];
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.yellow[200],
      appBar: AppBar(
        backgroundColor: Theme.of(context).primaryColor,
        title: Center(child: Text("TO DO")),
        elevation: 0,
      ),
      body: ListView.builder(
        itemCount: toDoList.length,
        itemBuilder: (context, index) {
          return TodoTile(
            taskName: toDoList[index]["task"], // Corrected key
            taskCompleted: toDoList[index]["completed"], // Corrected key
            onChanged: (value) => checkBoxChanged(value, index),
          );
        },
      ),
    );
  }
}

Firstly, make Function(bool?)? onChanged; final to allow constant constructor for widget.

Secondly, the main problem is in

List toDoList = [
    {"Make Tutorial", false},
    {"Do Exercise", false}
  ];

I would reccommend not to use raw types because IDE shows you that the type of toDoList is List<dynamic>. But if you would write this like

final toDoList = [ // or var but you never override it
      {"Make Tutorial", false},
      {"Do Exercise", false}
    ];

you would see that the type is actually List<Set<Object>> .

  void checkBoxChanged(bool? value, int index){
    setState(() {
      toDoList[index][1] = !toDoList[index][1];
    });
  }

Here, you are trying to get item of Set<Object> by index but it's impossible because set is not sorted as it calculates hashes to store items.

  1. Make data class for todo items containing String name and bool isChecked

  2. Don't use raw generics like List. Always specifiy the type or leave it to the compiler.

Also, you could replace Set in toDoList with List and it would worked but it's very nasty and unstable solution)

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论