Reputation: 1986
I am new to flutter and trying to create simple todo app using mobx. whenever I am adding a new task I can see new updated tasks data in my @action but it is not reflecting on UI.
main.dart
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Provider<TaskList>(
create: (content) => TaskList(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
),
);
}
}
taskList
@observable
List<Task> tasksList = [
Task(name: 'buy milk'),
Task(name: 'buy sugar'),
Task(name: 'buy bread'),
];
@action
void addTask(String title) {
final task = Task(name: title);
tasksList.add(task);
print(tasksList);
}
TodoApp class
class TodoApp extends StatelessWidget {
Widget buildBottomSheet(BuildContext context) {
return AddTaskScreen();
}
@override
Widget build(BuildContext context) => Provider<TaskList>(
create: (_) => TaskList(),
child: Scaffold(
appBar: AppBar(
title: const Text('Todos'),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.lightBlueAccent,
child: Icon(Icons.add),
onPressed: () {
showModalBottomSheet(
context: context,
//isScrollControlled: true,
builder: buildBottomSheet,
);
},
),
body: Column(
children: <Widget>[
TodoListView(),
],
),
),
);
}
TodoListView class
class TodoListView extends StatelessWidget {
@override
Widget build(BuildContext context) {
final list = Provider.of<TaskList>(context);
return Observer(
builder: (_) => Expanded(
child: ListView.builder(
itemBuilder: (content, index) {
return Observer(
builder: (_) => TaskTile(
taskTitle: list.tasksList[index].name,
isChecked: list.tasksList[index].isDone,
checkBoxCallback: (checkBoxState) {
// taskData.updateTask(task);
},
longPressCallBack: () {
list.deleteTask(index);
},
),
);
},
itemCount: list.tasksList.length,
),
),
);
}
}
TaskTile Class
class TaskTile extends StatelessWidget {
final String taskTitle;
final bool isChecked;
final Function checkBoxCallback;
final Function longPressCallBack;
TaskTile(
{this.taskTitle,
this.isChecked,
this.checkBoxCallback,
this.longPressCallBack});
@override
Widget build(BuildContext context) {
print('task tile');
print(taskTitle);
return ListTile(
title: Text(
taskTitle,
style: TextStyle(
decoration: isChecked ? TextDecoration.lineThrough : null,
),
),
trailing: Checkbox(
activeColor: Colors.lightBlueAccent,
value: isChecked,
onChanged: checkBoxCallback,
),
onLongPress: longPressCallBack,
);
}
}
AddTaskScreen Class
class AddTaskScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
String newTaskTitle;
final list = Provider.of<TaskList>(context);
return Container(
child: Container(
padding: EdgeInsets.only(left: 20.0, top: 20.0, right: 20.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(20.0), topLeft: Radius.circular(20.0)),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'Add a Task',
style: TextStyle(
fontSize: 30.0,
color: Colors.lightBlueAccent,
),
textAlign: TextAlign.center,
),
TextField(
autofocus: true,
textAlign: TextAlign.center,
onChanged: (newTask) {
newTaskTitle = newTask;
},
),
SizedBox(
height: 20.0,
),
FlatButton(
child: Text(
'Add',
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
padding: EdgeInsets.symmetric(vertical: 10.0),
onPressed: () {
list.addTask(newTaskTitle);
Navigator.pop(context);
// print('piyuhs');
// print(list);
},
color: Colors.lightBlueAccent,
),
],
),
),
);
}
}
in addTask
action value is updating but it is not reflecting on UI. I know I am doing silly mistake here.
I have search on google also but still not working.
Thanks in advance
Upvotes: 1
Views: 3511
Reputation: 788
It's a particular case of mobx indeed.
Actually the notification is fire to the UI when there is a change of instance not only parameter.
Here the list is the same instance and doesn't not trigger UI.
To work around this problem you have to make your list an ObservableList
:
@observable
ObservableList<Task> tasksList = ObservableList<Task>([ //Change here
Task(name: 'buy milk'),
Task(name: 'buy sugar'),
Task(name: 'buy bread'),
]);
@action
void addTask(String title) {
final task = Task(name: title);
tasksList.add(task);
print(tasksList);
}
It should do the job ;)
Upvotes: 3