Routing 2: Add New Dog Page

The only other page we will create is to add dogs.

The next section will show you how to handle user input, but you might as well add that route now, while we're on the subject.

1. Add NewDogPage

Create a new file in the lib folder called new_dog_form.dart.

The UI of this page is simple:

form page screen shot

Here's the code with no functionality (again, you'll add the user input functionality in the next section):

  1. // new_dog_form.dart
  2. import 'package:flutter/material.dart';
  3. class AddDogFormPage extends StatefulWidget {
  4. @override
  5. _AddDogFormPageState createState() => _AddDogFormPageState();
  6. }
  7. class _AddDogFormPageState extends State<AddDogFormPage> {
  8. @override
  9. Widget build(BuildContext context) {
  10. // new page needs scaffolding!
  11. return Scaffold(
  12. appBar: AppBar(
  13. title: Text('Add a new Dog'),
  14. backgroundColor: Colors.black87,
  15. ),
  16. body: Container(
  17. color: Colors.black54,
  18. child: Padding(
  19. padding: const EdgeInsets.symmetric(
  20. vertical: 8.0,
  21. horizontal: 32.0,
  22. ),
  23. child: Column(
  24. children: [
  25. Padding(
  26. padding: const EdgeInsets.only(bottom: 8.0),
  27. // Text Field is the basic input widget for Flutter.
  28. // It comes built in with a ton of great UI and
  29. // functionality, such as the labelText field you see below.
  30. child: TextField(
  31. decoration: InputDecoration(
  32. labelText: 'Name the Pup',
  33. )),
  34. ),
  35. Padding(
  36. padding: const EdgeInsets.only(bottom: 8.0),
  37. child: TextField(
  38. decoration: InputDecoration(
  39. labelText: "Pup's location",
  40. )),
  41. ),
  42. Padding(
  43. padding: const EdgeInsets.only(bottom: 8.0),
  44. child: TextField(
  45. decoration: InputDecoration(
  46. labelText: 'All about the pup',
  47. ),
  48. ),
  49. ),
  50. // A Strange situation.
  51. // A piece of the app that you'll add in the next
  52. // section *needs* to know its context,
  53. // and the easiest way to pass a context is to
  54. // use a builder method. So I've wrapped
  55. // this button in a Builder as a sort of 'hack'.
  56. Padding(
  57. padding: const EdgeInsets.all(16.0),
  58. child: Builder(
  59. builder: (context) {
  60. // The basic Material Design action button.
  61. return RaisedButton(
  62. // If onPressed is null, the button is disabled
  63. // this is my goto temporary callback.
  64. onPressed: () => print('PRESSED'),
  65. color: Colors.indigoAccent,
  66. child: Text('Submit Pup'),
  67. );
  68. },
  69. ),
  70. ),
  71. ],
  72. ),
  73. ),
  74. ),
  75. );
  76. }
  77. }

2. Add the Routing

Like the last section, you now have a page that you can't access. Add the button and routing information to the _MyHomePageState class.

  1. // main.dart
  2. @override
  3. Widget build(BuildContext context) {
  4. return Scaffold(
  5. appBar: AppBar(
  6. title: Text(widget.title),
  7. backgroundColor: Colors.black87,
  8. // This is how you add new buttons to the top right of a material appBar.
  9. // You can add as many as you'd like.
  10. actions: [
  11. IconButton(
  12. icon: Icon(Icons.add),
  13. onPressed: _showNewDogForm,
  14. ),
  15. ],
  16. ),
  17. ...

That will add a plus-sign looking button to the top right corner of your app, and finally you can add the method that builds a new route.

Import new_dog_form.dart in main.dart:

  1. // main.dart
  2. import 'package:flutter/material.dart';
  3. import 'dog_list.dart';
  4. import 'dog_model.dart';
  5. import 'new_dog_form.dart';

Add this anywhere in your _MyHomePageState class:

  1. // Any time you're pushing a new route and expect that route
  2. // to return something back to you,
  3. // you need to use an async function.
  4. // In this case, the function will create a form page
  5. // which the user can fill out and submit.
  6. // On submission, the information in that form page
  7. // will be passed back to this function.
  8. Future _showNewDogForm() async {
  9. // push a new route like you did in the last section
  10. Dog newDog = await Navigator.of(context).push(
  11. MaterialPageRoute(
  12. builder: (BuildContext context) {
  13. return AddDogFormPage();
  14. },
  15. ),
  16. );
  17. // A null check, to make sure that the user didn't abandon the form.
  18. if (newDog != null) {
  19. // Add a newDog to our mock dog array.
  20. initialDoggos.add(newDog);
  21. }
  22. }