Reputation: 65
everyone! I'm learning Flutter / Dart and keep having issues with instantiation and initialization. Currently I'm writing a reorderable list but for some reason, I can't populate the list because my instance has some issue... (I think the issue is at these lines below)
List<String> tasks = [];
MyTask t;
tasks = [ t.task = 'Buy ice cream', t.task = 'Learn Flutter', t.task = 'Read books' ];)
Can you check it and give me a clue? Thanks in advance. Any tip to seek docs is welcome! Exception:
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building _BodyBuilder:
The setter 'task=' was called on null.
Receiver: null
Tried calling: task="Buy ice cream"
Relevant code:
import 'package:flutter/material.dart';
import './bottomNavigationBar.dart';
import './ViewFeed.dart';
import './ViewNewTodo.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
//home: MyScaffold(),
initialRoute: '/',
routes: {
'/':(context) => MyFeed(),
'/toDo':(context) => MyScaffold(),
'/newToDo':(context) => MyNewTodo(),
},
);
}
}
class MyScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My ToDoS'),
),
body: MyReorderableTaskList(),
floatingActionButton: MyFloatingActionButtonNewTodo() ,
bottomNavigationBar: MyBottomNavigationBar(),
);
}
}
//Reorderable list elements
//FloatingActionButton
class MyFloatingActionButtonNewTodo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FloatingActionButton(
child: Icon(Icons.add),
tooltip: 'Idea',
onPressed: ()=>{ Navigator.pushNamed(context, '/newToDo') },
);
}
}
class MyTask{
String task;
MyTask(this.task);
}
//ReorderableListView implementation
class MyReorderableTaskList extends StatefulWidget {
@override
_MyReorderableTaskListState createState() => _MyReorderableTaskListState();
}
class _MyReorderableTaskListState extends State<MyReorderableTaskList> {
List<String> tasks = [];
MyTask t;
void initState(){
tasks = [ t.task = 'Buy ice cream', t.task = 'Learn Flutter', t.task = 'Read books' ];
super.initState();
}
@override
Widget build(BuildContext context) {
return ReorderableListView(
onReorder: _onReorder,
children: List.generate(
tasks.length,
(index){ return MyListView(index, Key('$index'), tasks ); }
),
);
}
void _onReorder(int oldIndex, int newIndex){
setState(() {
if(newIndex > oldIndex) { newIndex -= 1; }
final String item = tasks.removeAt(oldIndex);
tasks.insert(newIndex, item);
});
}
}
class MyListView extends StatefulWidget {
final int index;
final Key key;
final List<String> listTasks;
MyListView(this.index, this.key, this.listTasks);
@override
_MyListViewState createState() => _MyListViewState();
}
class _MyListViewState extends State<MyListView> {
@override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(6),
child: InkWell(
splashColor: Colors.blue,
onTap: ()=>{ MaterialState.focused },
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
title: Text('Tarea: ${widget.listTasks[widget.index]} | ${widget.index}',),
),
],
),
),
);
}
}
Upvotes: 0
Views: 1810
Reputation: 341
MyTask t;
is null. t
isn't actually anything yet. You must create a new object MyTask()
and assign it to t
Change it to
MyTask t = new MyTask("");
Edit: More thorough explanation
You can't just declare MyTask t;
and then try to use t
, because you have not yet said what t
is. That's like declaring int a;
and then trying to do print(a + 5)
. You can't do that, because you have not yet assigned a value to a
. Similarly, MyTask t;
means you have created a variable named t
of type MyTask
. In other words, you have declared a variable t
. But you must still initialize it, in other words, assign t
a value of type MyTask
, otherwise the value of t
will be null
.
So to summarize,
MyTask t;
t.task = "Hello";
will not work, because it's like doing
int a;
int b = a + 5;
You can't add 5 to a, because although you have declared the variable a
, you have not yet initialized it, so it does not yet have a value.
Likewise, you can't access the .task
property of t
, because you haven't said what t
is. t
is just null
.
So you must initialize t
by instantiating a new MyTask
object-
MyTask t = new MyTask("");
The ""
is required inside the parentheses because your MyTask class constructor requires a parameter.
class MyTask{
String task;
MyTask(this.task); // Parameter required to assign to the String task
}
Upvotes: 2