Bloc (State Management) Items add in the List Example

import "dart:async";
import "package:flutter/material.dart";

/// Todo class: This is a simple class that represents a todo item. It contains only one
/// field, title, which represents the title of the todo.
class Todo
{
final String title;
Todo(this.title);
}

///TodoBloc: This is a BLoC (Business Logic Component) class responsible for
/// managing the state of todo items. It has a stream controller _todoController to
/// handle todo data flow, and it exposes a todoStream to listen for changes in todo
/// data. It also provides methods to add todos (addTodo) and cleans up resources
/// (dispose).

class TodoBloc
{
final _todoController = StreamController<List<Todo>>.broadcast();
final List<Todo> _todos = [];

Stream<List<Todo>> get todoStream {
return _todoController.stream;
}

void addTodo(Todo todo) {
_todos.add(todo);
_todoController.sink.add(_todos);
}

void dispose()
{
_todoController.close();
}
}

void main()
{
runApp(const MyApp());
}
class MyApp extends StatelessWidget
{
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Todo App",
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.grey,
),
home: const TodoScreen(),
);
}
}

///TodoScreen: This is the main screen of the app. It is a stateful widget because it
/// needs to manage the state of the text controller (_controller) and the TodoBloc
/// (_todoBloc). It contains a Scaffold with an AppBar, a ListView.builder to display the
/// list of todos, and a FloatingActionButton to add new todos.
/// build method: This method builds the UI of the TodoScreen. It uses a StreamBuilder
/// to listen for changes in the todo list and update the UI accordingly. It also contains a
/// FloatingActionButton that displays a dialog to add new todos.
/// StreamBuilder: This widget listens to the stream of todos from the TodoBloc and
/// rebuilds the UI whenever there's a change in the todo list
/// FloatingActionButton: This button opens a dialog when pressed, allowing users to
/// add new todo items.

class TodoScreen extends StatefulWidget
{
const TodoScreen({super.key});
@override
State<TodoScreen> createState()
{
return TodoScreenState();
}
}
class TodoScreenState extends State<TodoScreen>
{
final TextEditingController _controller = TextEditingController();
final TodoBloc _todoBloc = TodoBloc();

@override
void dispose()
{
_controller.dispose();
_todoBloc.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Todo List"),
centerTitle: true,
backgroundColor: Colors.grey,
),
body: StreamBuilder<List<Todo>>(
stream: _todoBloc.todoStream,
builder: (context, snapshot) {
return ListView.builder(
itemCount: snapshot.data?.length ?? 0,
itemBuilder: (context, index) {
final todo = snapshot.data![index];
return Card(
child: ListTile(
leading: CircleAvatar(backgroundColor: Colors.grey.shade400, child: Text(todo.title[0])),
title: Text(todo.title),
subtitle: Text(todo.title),
trailing: const Icon(Icons.arrow_forward),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return DetailPage2(title: todo.title, image: todo.title[0]);
},
),
);
},
),
);
},
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text("Add Todo"),
content: TextFormField(
controller: _controller,
decoration: const InputDecoration(
hintText: "Enter todo",
),
),
actions: <Widget>[
TextButton(
onPressed: () {
_todoBloc.addTodo(Todo(_controller.text));
_controller.clear();
Navigator.pop(context);
},
style: TextButton.styleFrom(
backgroundColor: Colors.blue,
),
child: const Text("Add", style: TextStyle(color: Colors.white),),
),
],
);
},
);
},
backgroundColor: Colors.blue,
child: const Icon(Icons.add, color: Colors.white, size: 30.0),
),
);
}
}
class DetailPage2 extends StatelessWidget
{
const DetailPage2({super.key, required this.title, required this.image});
final String title;
final String image;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
centerTitle: true,
backgroundColor: Colors.grey,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircleAvatar(radius: 100.0,
backgroundColor: Colors.grey.shade400,
child: Text(image, style: const TextStyle(fontSize: 80.0, fontWeight: FontWeight.bold),),),
const SizedBox(height: 40.0),
Text(title, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 40.0),),
],
),
),
);
}
}

Comments

Popular posts from this blog

Second GET API Calling with Bloc simple Example in Flutter

Stack Container Scrollable Card widget UI with Custom Widget

Pagination with Bloc Pattern in Flutter