У меня есть AnimatedList, начальные элементы которого добавляются перед загрузкой данных из SharedPreferences. Есть ли способ, я могу сначала загрузить данные с устройства, а затем построить экран.
Допустим, я загружаю данные в myList
на для l oop, используя SharedPreferences. А затем используя данные из myList
для создания AnimatedList. Проблема, с которой я сталкиваюсь, заключается в том, что загруженные данные не отображаются в AnimatedList. AnimatedList получает сборку перед загрузкой данных.
import 'package:material_todo/index.dart';
class TaskScreen extends StatefulWidget {
TaskScreen({this.taskProvider});
final TaskProvider taskProvider;
@override
_TaskScreenState createState() => _TaskScreenState();
}
class _TaskScreenState extends State<TaskScreen>
with SingleTickerProviderStateMixin {
@override
void initState() {
super.initState();
widget.taskProvider.initialiseController(this);
}
String taskRemaining(List tasks) {
var remain = 0;
for (var i in tasks) {
if (i[2] == false) {
remain += 1;
}
}
return '$remain';
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kWhiteColor,
appBar: widget.taskProvider.editTask
? AppBar(
backgroundColor: Colors.black54,
title: Text('Edit mode'),
centerTitle: false,
leading: IconButton(
onPressed: () {
widget.taskProvider.selectTask(false);
widget.taskProvider.toggleAddTask(false);
widget.taskProvider.toggleEditTask(false);
},
icon: Icon(
Icons.close,
color: Colors.white,
),
),
actions: <Widget>[
IconButton(
onPressed: () {
widget.taskProvider.editingTask();
},
icon: Icon(
Icons.edit,
color: Colors.white,
),
),
IconButton(
onPressed: () {
widget.taskProvider.deleteTask();
widget.taskProvider.toggleEditTask(false);
widget.taskProvider.toggleAddTask(false);
},
icon: Icon(
Icons.delete,
color: Colors.white,
),
),
],
)
: AppBar(
title: Text(
'Tasks',
),
actions: <Widget>[
IconButton(
onPressed: () {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) =>
// SettingsScreen(provider: taskProvider),
// ),
// );
widget.taskProvider.clearData();
},
icon: Icon(
Icons.settings,
color: Colors.white,
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (widget.taskProvider.showAddTask) {
widget.taskProvider.toggleAddTask(false);
} else {
widget.taskProvider.toggleAddTask(true);
}
try {
widget.taskProvider.selectTask(false);
widget.taskProvider.toggleEditTask(false);
} catch (e) {
print(e);
}
},
child: RotationTransition(
turns: Tween(begin: 0.0, end: 0.125)
.animate(widget.taskProvider.rotationalController),
child: Icon(
Icons.add,
),
),
),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
widget.taskProvider.showAddTask
? BuildTaskInput(widget.taskProvider)
: Container(
height: 0,
width: 0,
),
Padding(
padding:
const EdgeInsets.only(left: 30.0, top: 30.0, bottom: 20.0),
child: Text(
taskRemaining(widget.taskProvider.tasks) + ' tasks remaining',
style: TextStyle(
fontSize: 20.0,
color: Colors.grey[800],
fontWeight: FontWeight.w500,
),
),
),
Expanded(
child: AnimatedList(
key: widget.taskProvider.listKey,
initialItemCount: widget.taskProvider.tasks.length,
itemBuilder: (context, index, animation) {
return SizeTransition(
sizeFactor: animation,
child: TaskTile(
title: widget.taskProvider.tasks[index][0],
due: widget.taskProvider.tasks[index][1],
isChecked: widget.taskProvider.tasks[index][2],
isSelected: widget.taskProvider.tasks[index][3],
changeValue: (newValue) {
widget.taskProvider.checkTask(newValue, index);
},
editTask: () {
widget.taskProvider.setTileIndex(index);
widget.taskProvider.selectTask(true);
widget.taskProvider.toggleEditTask(true);
},
),
);
}),
),
],
),
),
);
}
}
import 'package:material_todo/index.dart';
class TaskProvider extends ChangeNotifier {
TaskProvider() {
loadData();
}
//Properties
TextEditingController _textController = TextEditingController();
AnimationController _rotationController;
final GlobalKey<AnimatedListState> _listKey = GlobalKey();
int _tileIndex = 0; //index of selected tile.
bool _showAddTask = false; //whether to show add task container.
bool _editTask = false; // edit task.
bool _deleteCheckTasks = false;
bool _bottomCheckTasks = true;
List<List> _tasks = [
['abc', 'Today', false, false]
]; //stores all the task data.
//Getters
List<List> get tasks => _tasks;
bool get showAddTask => _showAddTask;
bool get editTask => _editTask;
bool get deleteCheckTasks => _deleteCheckTasks;
bool get bottomCheckTasks => _bottomCheckTasks;
int get tileIndex => _tileIndex;
TextEditingController get textController => _textController;
AnimationController get rotationalController => _rotationController;
GlobalKey<AnimatedListState> get listKey => _listKey;
//Setters
void setTileIndex(int index) {
_tileIndex = index;
notifyListeners();
}
void addTask(String title, String due) {
int index = addTaskAtProperIndex(due);
_tasks.insert(index, [
title,
due,
false,
false,
]);
_listKey.currentState.insertItem(index);
notifyListeners();
saveData();
}
void toggleAddTask(bool value) {
_showAddTask = value;
if (!value) {
_rotationController.reverse();
_textController.clear();
} else {
_rotationController.forward();
}
notifyListeners();
print(value);
}
void toggleEditTask(bool value) {
_editTask = value;
notifyListeners();
}
void toggleDeleteTask(bool value) {
_deleteCheckTasks = value;
if (value) {
for (int i = _tasks.length - 1; i >= 0; i--) {
if (_tasks[i][2] == true) {
_tasks.removeAt(i);
}
}
}
notifyListeners();
saveData();
}
void toggleBottomCheckTask(bool value) {
_bottomCheckTasks = value;
if (value) {
for (int i = _tasks.length - 1; i >= 0; i--) {
if (_tasks[i][2] == true) {
_tasks.add(_tasks[i]);
_tasks.removeAt(i);
}
}
}
notifyListeners();
saveData();
}
void checkTask(bool value, int index) {
_tasks[index][2] = value;
if (value && _deleteCheckTasks) {
deleteTask();
}
if (value && _bottomCheckTasks) {
_tasks.add(_tasks[index]);
_tasks.removeAt(index);
}
notifyListeners();
saveData();
}
void selectTask(bool value) {
_tasks[_tileIndex][3] = value;
notifyListeners();
saveData();
}
void deleteTask() {
_tasks.removeAt(_tileIndex);
notifyListeners();
saveData();
}
void replaceTask(String title, String due) {
_tasks.removeAt(_tileIndex);
addTask(title, due);
selectTask(false);
toggleEditTask(false);
notifyListeners();
saveData();
}
void editingTask() {
toggleAddTask(true);
_textController.value = TextEditingValue(text: _tasks[_tileIndex][0]);
}
int addTaskAtProperIndex(String due) {
for (int i = 0; i < _tasks.length; i++) {
if (_tasks[i][1] == due) {
return i;
}
if (due == 'Today') {
return 0;
}
if (due == 'Tomorrow') {
for (int i = _tasks.length - 1; i >= 0; i--) {
if (_tasks[i][1] == 'Today') {
return i + 1;
}
}
return 0;
}
if (due == 'Anytime') {
for (int i = _tasks.length - 1; i >= 0; i--) {
if (_tasks[i][1] == 'Tomorrow') {
return i + 1;
}
}
for (int i = _tasks.length - 1; i >= 0; i--) {
if (_tasks[i][1] == 'Today') {
return i + 1;
}
}
return 0;
}
}
return 0;
}
void initialiseController(TickerProvider ticker) {
_rotationController = AnimationController(
duration: const Duration(milliseconds: 200), vsync: ticker);
}
void saveData() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
_prefs.setInt('count', _tasks.length);
_prefs.setBool('deleteCheckTasks', _deleteCheckTasks);
_prefs.setBool('bottomCheckTasks', _bottomCheckTasks);
for (int i = 0; i < _tasks.length; i++) {
_prefs.setString('$i 0', _tasks[i][0]);
_prefs.setString('$i 1', _tasks[i][1]);
_prefs.setBool('$i 2', _tasks[i][2]);
}
print('data saved successfully');
}
Future loadData() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
var _count = _prefs.getInt('count');
if (_count != null) {
for (int i = 0; i < _count; i++) {
var _title = _prefs.getString('$i 0');
var _due = _prefs.getString('$i 1');
var _check = _prefs.getBool('$i 2');
_tasks.add([_title, _due, _check, false]);
}
print('dada loaded successfully');
} else {
print('No data was found');
}
if (_prefs.getBool('deleteCheckTasks') != null) {
_deleteCheckTasks = _prefs.getBool('deleteCheckTasks');
}
if (_prefs.getBool('bottomCheckTasks') != null) {
_bottomCheckTasks = _prefs.getBool('bottomCheckTasks');
}
notifyListeners();
}
Future clearData() async {
SharedPreferences _prefs = await SharedPreferences.getInstance();
_prefs.clear();
}
}