I'm new to Flutter and I'm experimenting AnimatedList in my todolist app. I have ensured that:
- globalkey is initialised
- Uniquekey is used
But, whenever I tried to execute my app, it says that currentState is null.
//TaskList.dart, where it shows all the TaskTile
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../models/TaskData.dart';
import 'task_tile.dart';
import 'package:todoey/models/Task.dart';
class TasksList extends StatelessWidget {
final GlobalKey<AnimatedListState> _key = GlobalKey();
//the acccess the state of Animated list
void removeTask(int index, TaskData taskData) {
final task = taskData.tasks[index];
Future.delayed(Duration(milliseconds: 700), () {
if (_key.currentState == null) {
print('currentState is null');
} else {
_key.currentState!.removeItem(index, (context, animation) {
return SizeTransition(
sizeFactor: animation,
child: TaskTile(
text: task.name,
isChecked: task.isDone,
checkBoxCallBack: (checkboxState) {},
onLongPressCallback: () {},
),
);
}, duration: Duration(milliseconds: 700));
taskData.deleteTask(task);
}
});
}
@override
Widget build(BuildContext context) {
//ListView
//which builds the children on demand
//This constructor is appropriate for list views with a large (or infinite) number of children
// the builder is called only for those children that are actually visible.
//Consumer widget simplifies the 'Provider.of<TaskData>(context)' into just 'taskData'
//when taskData is updated it gonna rebuild
return Consumer<TaskData>(
builder: (context, taskData, child) {
return AnimatedList(
itemBuilder: (context, index, animation) {
final task = taskData.tasks[index];
return SizeTransition(
key: UniqueKey(),
sizeFactor: animation,
child: TaskTile(
text: task.name,
isChecked: task.isDone,
checkBoxCallBack: (checkboxState) {
taskData.doneToggle(task);
},
onLongPressCallback: () {
removeTask(index, taskData);
},
),
);
},
initialItemCount: taskData.taskCount,
);
},
);
}
}
\\TaskTile
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:todoey/models/TaskData.dart';
import '../models/Task.dart';
class TaskTile extends StatefulWidget {
final String text;
final bool isChecked;
final Function(bool?) checkBoxCallBack;
final Function() onLongPressCallback;
TaskTile({
required this.text,
required this.isChecked,
required this.checkBoxCallBack,
required this.onLongPressCallback,
});
@override
State<TaskTile> createState() => _TaskTileState();
}
class _TaskTileState extends State<TaskTile> {
// void checkBoxCallBack(bool? checkBoxState) {
@override
Widget build(BuildContext context) {
return GestureDetector(
onLongPress: widget.onLongPressCallback,
child: CheckboxListTile(
title: Text(
widget.text,
style: TextStyle(
color: Colors.black,
decoration:
widget.isChecked ? TextDecoration.lineThrough : null),
),
value: widget.isChecked,
onChanged: widget.checkBoxCallBack),
);
}
}
\\TaskData
import 'package:flutter/foundation.dart';
import 'Task.dart';
import 'dart:collection';
class TaskData extends ChangeNotifier {
List<Task> _tasks = [
Task('Buy milk'),
Task('watch hentai'),
Task('watch hentai'),
];
//The tasks return is not modifiable
//unmodifiable view of a list (not listview)
//the prevent we modify the task through the getter
UnmodifiableListView<Task> get tasks {
return UnmodifiableListView(_tasks);
}
void addTask(String text) {
final task = Task(text);
_tasks.add(task);
notifyListeners();
}
int get taskCount {
return _tasks.length;
}
void doneToggle(Task task) {
task.doneToggle();
notifyListeners();
}
void deleteTask(Task task) {
_tasks.remove(task);
notifyListeners();
}
}
- I tried to change TaskList to stateful widget
- I tried to Future.delay to see if there's any positive effect
None of my approaches worked. I need some help on this, any advice will be highly appreciated as I'm still a uni student and my universtiy haven't taught anything about mobile dev, thanks in advance!!!