The HomePage screen user interface

The HomePage screen will read data from the BLoC and show a ListView containing the Todo objects to the user. From this screen, the user will also write to the BLoC by deleting an object when they swipe an element from the ListView:

  1. In the main.dart file, edit the imports so that they contain a reference to the todo_bloc.dart file and a file that we will add shortly called todo_screen.dart. Remove all other imports:
import 'package:flutter/material.dart';
import 'todo_screen.dart';
import 'data/todo.dart';
import 'bloc/todo_bloc.dart';
  1. At the beginning of the _HomePageState class, create a field for the TodoBloc and one for the List of Todo that will be shown on the screen, and remove the preexisting code:
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
TodoBloc todoBloc;
List<Todo> todos;
}
  1. Override the initState() method and inside the function, let's set the todoBloc field to be an instance of the TodoBLoc class. This creates an instance of the BLoC:
 @override
void initState() {
todoBloc = TodoBloc();
super.initState();
}
  1. Also override the dispose() method so we don't forget to do it later. Here, we'll just call the dispose() method of the todoBloc object: 
@override
void dispose() {
todoBloc.dispose();
super.dispose();
}
  1. In the build() method, add the code to create a new empty todo and to populate the list of Todo objects that we called todos. The todoList property of the BLoC contains the objects retrieved from the database:
  @override
Widget build(BuildContext context) {
Todo todo = Todo('', '', '', 0);
todos = todoBloc.todoList;

}
  1. Then, still in the build() method, return a Scaffold whose AppBar will have a title of 'Todo List', and a body with a Container:
return Scaffold(
appBar: AppBar(
title: Text('Todo List'),
),
body: Container()
);

Finally, after building all the plumbing for our app, we can use the Streambuilder widget. This will listen to the events from the Stream and will rebuild all its descendants, using the latest data in the Stream. You can connect it to the Streams through the stream property and a builder that contains the UI that needs to be updated. We can also set the initialData property to make sure we control what is shown at the beginning before we receive any event.

  1. In the Container, add a Streambuilder as a child that connects to the todos Stream of the todoBloc instance, and has the todos list as the initial data: as you might remember, you use a StreamBuilder to build the widgets that will use the BLoC data:
child: StreamBuilder<List<Todo>>(
stream: todoBloc.todos,
initialData: todos,
)
  1. Then set the builder method, which takes the context, and the snapshot, which contains the data received from the Stream:
builder: (BuildContext context, AsyncSnapshot snapshot) {}
  1. Inside the builder method of the StreamBuilder, add a ListView.builder. For the itemCount parameter, we'll use a ternary operator. If the snapshot.hasData property is true, we'll use the length of the data contained in the snapshot; otherwise, we'll use 0. Then we'll set an empty itembuilder for the ListView:
return ListView.builder(
itemCount: (snapshot.hasData) ? snapshot.data.length : 0,
itemBuilder: (context, index) {}
);
  1. In the builder function of the ListView, return a Dismissible so that the user will be able to swipe on the item and delete the Todo from the sembast database. This will happen by the app calling the todoDeleteSink and adding the Todo at the index position. This is step 10 of the BLoC guideline in the previous section:
return Dismissible(
key: Key(snapshot.data[index].id.toString()),
onDismissed: (_) =>
todoBloc.todoDeleteSink.add(snapshot.data[index])
);
  1. The child of the Dismissible widget is a ListTile that shows the priority in a CircleAvatar, then the name of the Todo as title, and the description as subtitle. Add the following code to set the ListTile in the Dismissible widget:
child: ListTile(
leading: CircleAvatar(
backgroundColor: Theme.of(context).highlightColor,
child: Text("${snapshot.data[index].priority}"),
),
title: Text("${snapshot.data[index].name}"),
subtitle: Text("${snapshot.data[index].description}"),
)

Still inside the ListTile, we'll add a trailing icon. When the user presses the icon, the app will bring them to the second screen of the app, which shows the todo detail and allows the user to edit and save the todo that they selected. As this is for editing, we'll choose the Icons.edit icon, and in the onPressed function, we'll use the Navigator.push() method to navigate to the TodoScreen that we'll create right after completing this screen. We'll pass to the to-be-created screen the todo that was selected and a Boolean (false) that tells the screen that this is not a new todo, but an existing one.

  1. Add the following code to create a trailing IconButton and navigate to the second screen of the app:
trailing: IconButton(
icon: Icon(Icons.edit),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TodoScreen(
snapshot.data[index], false)),
);
},
),
  1. In the Scaffold, under the appBar, set a FloatingActionButton that the user will press to create a new Todo. This will also navigate to the second screen of the app, but this time the boolean value that is passed is true, as this is a new todo.
  1. Add the following code in the Scaffold to add the FloatingActionButon:
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) =>
TodoScreen(todo, true)),
);
},
),

Now that the HomePage screen is ready, let's add the TodoScreen next.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.149.238