Editing and deleting existing places

The easiest way to add the features to edit and delete items from the database is probably by creating a new screen with a ListView widget, containing all the items that were saved. In order to achieve this, we'll create a new screen in our app, as follows:

  1. In the lib folder, create a new file called manage_places.dart.
  1. After importing the material.dart library, we'll also import the place_dialog.dart file and our dbhelper.dart, as follows:
import 'package:flutter/material.dart';
import 'place_dialog.dart';
import 'dbhelper.dart';
  1. Inside this file, we'll create a new stateless widget, calling it ManagePlaces. This will contain a Scaffold whose AppBar title is 'Manage Places', and, in the body, we'll call a new widget, called PlacesList, that we'll create next, as follows:
class ManagePlaces extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Manage Places'),),
body: PlacesList(),
);
}
}

  1. Now, we need to create the PlacesList class. It will be a stateful widget. At the top of the class, we'll call an instance of DbHelper, calling it helper, which includes the methods to interact with the database, and, in the build() method, we'll return a ListView.builder() constructor, as shown in the following code block:
class PlacesList extends StatefulWidget {
@override
_PlacesListState createState() => _PlacesListState();
}

class _PlacesListState extends State<PlacesList> {
DbHelper helper = DbHelper();
@override
Widget build(BuildContext context) {
return ListView.builder()
}
}

The itemCount parameter contains the length of the placesList of the helper object. For the itemBuilder, we'll return a Dismissible to make it easy for the user to delete an item through a gesture. As you may remember, a Dismissible requires a key, which, in this case will be the name of the item in the places list, at the current position.

  1. In the DbHelper class in the dbhelper.dart file, let's add the method that will delete a record from the places table. We'll use the delete() helper method of the database to remove the Place, as illustrated in the following code block:
Future<int> deletePlace(Place place) async {
int result = await db.delete("places", where: "id = ?", whereArgs: [place.id]);
return result;
}

For the onDismissed function, we can call the deletePlace() method of the helper object, passing the place at the current position. Then, we call the setState() method to update the UI, and we show a message using a SnackBar, informing the user that the Place has been removed, as illustrated in the following code block:

  Widget build(BuildContext context) {
return ListView.builder(
itemCount: helper.places.length,
itemBuilder: (BuildContext context, int index) {
return Dismissible(
key: Key(helper.places[index].name),
onDismissed: (direction) {
String strName = helper.places[index].name;
helper.deletePlace(helper.places[index]);
setState(() {
helper.places.removeAt(index);
});
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text("$strName
deleted")));
},
));
},
);
  1. For the child of the Dismissible, we can use a ListTile, whose title is the name of the Place at the current position. For the trailing parameter, we'll use an IconButton, whose icon is the edit icon.

When the user presses the IconButton, we want to call an instance of PlaceDialog to allow the user to edit an existing Place. Note that when we create the instance of PlaceDialog, we are passing false as the second parameter, as this is NOT a new Place, but an existing one. This is illustrated in the following code block:

child:ListTile(
title: Text(helper.places[index].name),
trailing: IconButton(
icon: Icon(Icons.edit),
onPressed: () {
PlaceDialog dialog = PlaceDialog(helper.places[index],
false);
showDialog(
context: context,
builder: (context) =>
dialog.buildAlert(context));
},
),
  1. Now, we need a way to call this screen from the main screen of the app. From the main.dart file, in the build() method of the _MainMapState class, we can add an actions parameter to the Scaffold.

Here, we can add an IconButton, with a list icon, which, when pressed, will create a MaterialPageRoute that builds an instance of ManagePlaces and calls the Navigator.push() method, to change the screen and show the ListView with the saved places, instead of showing the map, as follows:

return Scaffold(
appBar: AppBar(title: Text('The Treasure Mapp'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.list),
onPressed: () {
MaterialPageRoute route =
MaterialPageRoute(builder: (context)=>
ManagePlaces());

Navigator.push(context, route);

},
),
],
),
  1. If you try the app right now, when you click the IconButton list, you should see your list of saved places, as shown in the following screenshot:

If you swipe any of the places in the list, the place will be deleted, and you'll see the SnackBar confirmation message. If you press the edit IconButton, you'll see the dialog with the name and coordinates of the place you've selected, and you'll be able to change the place data.

Now, there's one last feature that we need to introduce in our app, and it's the ability to shoot pictures and add them to the places: let's do that next.

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

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