Everything is nicer when you can add points on a Flutter map

The complete Flutter code so far, is at the end of the article.

After been able to display points on a map, I will change my App and Web API to add new points from my Mobile App.

This article is a follow up on:

FloatingActionButton

To get started, I will add a simple “FloatingActionButton”, these are circular buttons that appear at the bottom of the screen, and are very convenient and easy to use.

First I will change my build to contemplate my new button:

adding a floatingActionButton

My FloatingActionButton will be returned from a function, which will return one of 2 buttons, one to set the new marker, and another to submit after the new marker has been set.

return floatingActionButton

This function will also call 2 other functions depending on the var “newMarker” state, first when its null and we need to set the marker location:

setting newMarker Position

Initial FloatingActionButton

When I first set my “newMarker”, I will be calling the function “setNewMarker” to set it’s starter location at the center

setting newMarker position

Submit new Point FloatingActionButton

After I’ve added the marker to the location I want, I will have another button on the “floatingActionButton” to submit the new entry

open submit newMarker form

The button for submitting the new point will use “Navigator”, which is used to navigate to other screens I created, this will open a new screen with a form to complete the point information. Note that I’m passing the “newMarker” I had set earlier to the “NewEntry” screen/Widget.

Later I will show more about the “NewEntry” screen I will Navigate to.

Code improvements

I’ve done a small restructure of my original “getMap” function:

new getMap and newMarker

It now checks if the “newMarker” is not null, when it is, it will display only the markers already submitted, if it’s not null it will display the marker I’m setting.

My original “getMyData” also has a small change:

new getMyData

To make the code more readable, I’ve created a couple of functions to deal with filling my “_makers”, because I’m going to update this info in more than one place:

fill my _marker

Creating a new Class

Now, I’m going back to that “NewEntry” I mentioned earlier, I’m going to create a file named “newEntry.dart”, and add my first Stateless widget:

NewEntry Stateless Widget

Stateless Widgets is a widget (that can be made of many other widgets), that never changes state. Unlike Statefull Widget, we can not use “setState”, and it can not be changed after it was created. It is said that we should always start with a Stateless widget, and only switch to Statefull when it is completely necessary.

I’ve also added a parameter which is required to initiate this class, “newPoint”, this could be compared to a “QueryString” from my URL, since I’m more used to the Web. This parameter will be used to pass the latitude and longitude from my marker, to my Web API.

Form Validation

New Entry Form

I’m going create a Form with a GlobalKey to use validation, so that it is only submitted after Title and Description are filled. Both fields will have a validator.

Note: I have to pass “BuildContext context” to my function, because since we are using a Stateless Widget, we need to pass it when the widget is first built, we can’t access it directly after that.

As an example, for the Title, I use the TextFormField, with a controller associated (controllers give you access to what has been filled on that field), and on validator I will just check if it’s empty. If it’s not empty it will return a null and we will be able to continue:

Title Field

To make sure all the fields are filled before proceeding, all I have to do is call “_formKey.currentState.validate()”, it will validate the fields with a validator, if nothing is wrong, it will continue:

Save Button

MediaQuery, you can get information about the size and layout of the screen of a device.

In the previous code, I’ve a call to my Web API, “List result = await requestNewPoint();”, the result can be sent back to the “main.dart” with a simple “Navigator.pop(context, result);”. This simply closes the current screen and returns a value (result). On the main.dart I’m waiting to receive this data because I’m waiting for it:

It’s like opening a popup, and waiting for a result from it.

Validation