I want to access one or more lists or variables throughout the tree of my program and also perform operations of adding, deleting, editing on that list, I solve this problem by using the provider package as below figure:
I in first make this class
class TaskData extends ChangeNotifier {
List<Task> _tasks = [
Task(title: 'Buy Milk'),
Task(title: 'Buy Eggs'),
Task(title: 'Buy Bread'),
];
UnmodifiableListView<Task> get tasks => UnmodifiableListView(_tasks);
int get taskCount => _tasks.length;
toggleDone(index) {
_tasks[index].toggleDone();
notifyListeners();
}
addTask(data) {
_tasks.add(Task(title: data));
}
removeTask(index) {
_tasks.removeAt(index);
notifyListeners();
}
}
Then provide tree like this
void main() {
runApp(ChangeNotifierProvider(
create: (BuildContext context) => TaskData(),
child: MaterialApp(
theme: ThemeData(
useMaterial3: true,
),
home: TasksScreen(),
),
));
}
And i use like this code
class TasksList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<TaskData>(
builder: (context, taskData, child) {
return ListView.builder(
itemCount: taskData.taskCount,
itemBuilder: (context, index) {
print(taskData.tasks[index]);
return TaskTile(
taskTitle: taskData.tasks[index].title,
isChecked: taskData.tasks[index].isDone,
checkboxCallback: (newValue) {
taskData.toggleDone(index);
},
listTileCallback: () {
taskData.removeTask(index);
},
);
},
);
},
);
}
}
Now, I need to learn how to do this with the bloc and flutter_bloc and clean architecture that such as model class and entity class and repository class and all clean architecture system?
class Task extends Equatable { //import 'package:equatable/equatable.dart';
const Task({
required this.title,
this.isDone = false,
});
final String title;
final bool isDone;
@override
List<Object?> get props => [title, isDone];
Task copyWith({
String? title,
bool? isDone,
}) {
return Task(
title: title ?? this.title,
isDone: isDone ?? this.isDone,
);
}
}
abstract class TaskEvent extends Equatable {
const TaskEvent();
@override
List<Object> get props => [];
}
class ToggleDone extends TaskEvent {
const ToggleDone(this.task);
final Task task;
@override
List<Object> get props => [task];
}
class AddTask extends TaskEvent {
const AddTask(this.task);
final Task task;
@override
List<Object> get props => [task];
}
class RemoveTask extends TaskEvent {
const RemoveTask(this.task);
final Task task;
@override
List<Object> get props => [task];
}
///state
class TaskState extends Equatable {
const TaskState(this.tasks);
final List<Task> tasks;
@override
List<Object> get props => [tasks, identityHashCode(this)];
}
//bloc
class TaskBloc extends Bloc<TaskEvent, TaskState> {
TaskBloc([List<Task> tasks = const []]) : super(TaskState(tasks)) {
on<ToggleDone>((event, emit) {
final item = event.task;
final tasks = state.tasks;
final index = tasks.indexWhere((element) => element == item);
tasks[index] = item.copyWith(isDone: !item.isDone);
emit(TaskState([...tasks]));
});
on<AddTask>(
(event, emit) {
final tasks = state.tasks;
tasks.add(event.task);
emit(TaskState([...tasks]));
},
);
on<RemoveTask>((event, emit) {
final tasks = state.tasks;
tasks.remove(event.task);
emit(TaskState([...tasks]));
});
}
}
And Main file
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
List<Task> _tasks = [
Task(title: 'Buy Milk'),
Task(title: 'Buy Eggs'),
Task(title: 'Buy Bread'),
];
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(create: (context) => TaskBloc(_tasks)),
],
child: MaterialApp(
home: Scaffold(
body: TasksList(),
),
),
);
}
}
class TasksList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<TaskBloc, TaskState>(
builder: (context, taskData) {
return ListView.builder(
itemCount: taskData.tasks.length,
itemBuilder: (context, index) {
print(taskData.tasks[index]);
return ListTile(
title: Text(taskData.tasks[index].title),
leading: Checkbox(
value: taskData.tasks[index].isDone,
onChanged: (value) {
context
.read<TaskBloc>()
.add(ToggleDone(taskData.tasks[index]));
}),
trailing: IconButton(
onPressed: () {
context
.read<TaskBloc>()
.add(RemoveTask(taskData.tasks[index]));
},
icon: Icon(Icons.delete)),
);
},
);
},
);
}
}
You can follow bloclibrary and their example code .