Design Flutter UI: NoWar App Challenge

How to design a Flutter UI or user interface? That is one of the main challenges that very Flutter developer face while building a Flutter App.

For example, a challenge always ignites our passion to develop our skill. Certainly, this is no exception.

We have just started and built a part of the NoWar app. However, we can take it as a challenge to complete and make it a finished Flutter App.

We have already seen the First Step where we have mainly built the home page. In this section, we will build a few other pages. In addition, we will also use some material deign-related Widgets.

Firstly, let us see the screenshots of the pages that we have finished so far.

Secondly, we will watch the code of the pages where we have used the material design-related widgets.

Finally, I will leave this NoWar App to your disposal to complete as a challenge. I will give the link of the GitHub repository at the end of this section.

Certainly, ending war and bringing peace to this planet is a challenge.

Always.

No War App Homepage first
No War App Homepage first

This is our home page from where we can move to several pages. However, we have defined each section as a class in our model folder, so that we can follow the MVC design.

The plan is simple. We should click each icon to reach a home page. Like the 1700 century icon represents a home page from where we can go to other page that describes a war.

How to design Flutter UI

As we will follow the same material design pattern, that will take time to build the pages. But, more or less, we will have to do the same task for several times.

Again from that page, we can go back to the home page, or go to the next page.

As you’re guessing, we need to create several pages. In addition, we will link the pages. So our app should not crash while we navigate to other pages, or come back.

That part belongs to the “routes” property of the MaterialApp widget which we have discussed earlier.

Suppose we click the 1700 century icon. As a result, that will take us to the home page where we will describe five links.

Design Flutter UI NoWar App Challenge one
Design Flutter UI NoWar App Challenge one

Let us see the code of this page first.

import 'package:flutter/material.dart';
import '../../model/seventeen_hundred_wars.dart';
import 'seventeen_first.dart';

class SeventeenHome extends StatefulWidget {
  static const routeNname = '/seventen-home';
  const SeventeenHome({Key? key}) : super(key: key);

  @override
  _SeventeenHomeState createState() => _SeventeenHomeState();
}

class _SeventeenHomeState extends State<SeventeenHome> {
  List<SeventeenHundredWars> seventeenWars = [
    seventeenHundredWars[0],
    seventeenHundredWars[1],
    seventeenHundredWars[2],
    seventeenHundredWars[3],
    seventeenHundredWars[4],
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            backgroundColor: Colors.white,
            stretch: true,
            expandedHeight: 350.0,
            flexibleSpace: FlexibleSpaceBar(
              background: Container(
                padding: const EdgeInsets.all(8.0),
                child: Image.network(
                    'https://cdn.pixabay.com/photo/2017/08/01/14/42/knight-2565957_960_720.jpg'),
              ),
              stretchModes: const [
                StretchMode.zoomBackground,
              ],
            ),
          ),
          SliverFixedExtentList(
            itemExtent: 450,
            delegate: SliverChildListDelegate([
              Container(
                color: Colors.white,
                child: Column(
                  mainAxisSize: MainAxisSize.max,
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  // text direction does the same thing horizontally
                  verticalDirection: VerticalDirection.down,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        'Five Bloody Battles - 1700',
                        style: TextStyle(
                            fontSize: 50.0,
                            fontWeight: FontWeight.bold,
                            fontFamily: 'Schuyler',
                            foreground: Paint()
                              ..color = Colors.red
                              ..strokeWidth = 2.0
                              ..style = PaintingStyle.stroke),
                        textAlign: TextAlign.center,
                      ),
                    ),
                    GestureDetector(
                      onTap: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (context) => const SeventeenFirst()),
                        );
                      },
                      child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Text(
                          '1. ${seventeenWars[0].name}',
                          style: TextStyle(
                              fontSize: 21.0,
                              fontWeight: FontWeight.bold,
                              fontFamily: 'Trajan Pro',
                              foreground: Paint()
                                ..color = Colors.blue
                                ..strokeWidth = 2.0
                                ..style = PaintingStyle.stroke),
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        '2. ${seventeenWars[1].name}',
                        style: TextStyle(
                            fontSize: 21.0,
                            fontWeight: FontWeight.bold,
                            fontFamily: 'Trajan Pro',
                            foreground: Paint()
                              ..color = Colors.blue
                              ..strokeWidth = 2.0
                              ..style = PaintingStyle.stroke),
                        textAlign: TextAlign.center,
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        '3. ${seventeenWars[2].name}',
                        style: TextStyle(
                            fontSize: 21.0,
                            fontWeight: FontWeight.bold,
                            fontFamily: 'Trajan Pro',
                            foreground: Paint()
                              ..color = Colors.blue
                              ..strokeWidth = 2.0
                              ..style = PaintingStyle.stroke),
                        textAlign: TextAlign.center,
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        '4. ${seventeenWars[3].name}',
                        style: TextStyle(
                            fontSize: 21.0,
                            fontWeight: FontWeight.bold,
                            fontFamily: 'Trajan Pro',
                            foreground: Paint()
                              ..color = Colors.blue
                              ..strokeWidth = 2.0
                              ..style = PaintingStyle.stroke),
                        textAlign: TextAlign.center,
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Text(
                        '5. ${seventeenWars[4].name}',
                        style: TextStyle(
                            fontSize: 21.0,
                            fontWeight: FontWeight.bold,
                            fontFamily: 'Trajan Pro',
                            foreground: Paint()
                              ..color = Colors.blue
                              ..strokeWidth = 2.0
                              ..style = PaintingStyle.stroke),
                        textAlign: TextAlign.center,
                      ),
                    ),
                  ],
                ),
              ),
              Container(),
            ]),
          ),
        ],
      ),
    );
  }
}

As we see, we have used the CustomScrollView Widget so that we can scroll down the page.

After that we want that the AppBar section will shrink or resize as we scroll down as follows.

Design Flutter UI NoWar App Challenge two
Design Flutter UI NoWar App Challenge two

We can make it happen by using the SliverAppBar Widget. You may read how to collapse the header section.

We follow the same technique in the next page.

Design Flutter UI NoWar App Challenge three
Design Flutter UI NoWar App Challenge three

How to use model class to design Flutter UI?

In the previous section we have seen how to use the List methods to use our model class where we have defined many properties.

Let us see one of the model class from where we have got the images.

import 'weapon_used.dart';

class SeventeenHundredWars {
  String imageUrl;
  int centuries;
  String name;
  String place;
  int howManyDied;
  String description;
  List<WeaponUsed> weapons;
  String summary;

  SeventeenHundredWars({
    required this.imageUrl,
    required this.centuries,
    required this.name,
    required this.place,
    required this.howManyDied,
    required this.description,
    required this.weapons,
    required this.summary,
  });
}

List<SeventeenHundredWars> seventeenHundredWars = [
  SeventeenHundredWars(
    imageUrl:
        'https://cdn.pixabay.com/photo/2016/03/27/07/38/police-1282330_960_720.jpg',
    centuries: 1700,
    name: 'War of the Spanish Succession 1701–1714',
    place: 'Europe',
    howManyDied: 100000,
    description:
        'Who would be to the throne of Spain following the death of the childless Charles II;'
        ' The last of the Spanish Habsburgs?'
        ' The conflict arose from this question. Although three principal claimants '
        'England, the Dutch Republic, and France signed a treaty of partition in October 1698, it did'
        ' not last. A major conflict arose that centered around one question - who would occupy'
        ' most places. An anti-French alliance was formed (September 7, 1701) by England, the Dutch Republic, and the emperor Leopold. '
        ' They were later joined by Prussia, Hanover, other German states, and Portugal.'
        ' On the other side, The electors of '
        ' Bavaria and Cologne and the dukes of Mantua and Savoy allied themselves with France, although Savoy switched sides in 1703.'
        'John Churchill, duke of Marlborough, played the leading role in Queen Anne’s government and on the battlefield until his fall in 1711. '
        ' He was ably supported on the battlefield by the imperial general Prince Eugene of Savoy.'
        ' In Britain the enemies of Marlborough won influence with the queen and had him removed from command on December 31, 1711. '
        ' With the collapse of the alliance, peace negotiations began in 1712. '
        ' Because of the conflicts of interest between the former allies, each dealt separately with France.',
    weapons: weapons,
    summary: 'Treaties of Utrecht marked the rise of the power of Britain',
  ),
  SeventeenHundredWars(
    imageUrl:
        'https://cdn.pixabay.com/photo/2014/10/02/06/34/war-469503_960_720.jpg',
    centuries: 1700,
    name: 'Great Northern War 1717–1720.',
    place: 'Europe',
    howManyDied: 10000,
    description:
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vestibulum metus ac quam laoreet accumsan. Sed quis ultrices massa, quis elementum nunc. Nam a massa varius lacus suscipit fringilla.',
    weapons: weapons,
    summary: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
  ),
  SeventeenHundredWars(
    imageUrl:
        'https://cdn.pixabay.com/photo/2017/11/08/12/04/war-2930223_960_720.jpg',
    centuries: 1700,
    name: 'War of the Austrian Succession 1740.',
    place: 'Europe',
    howManyDied: 15000,
    description:
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla odio ipsum, rhoncus id libero id, pretium congue sem. Nunc vitae ultricies justo. In ac nunc a ligula lobortis mattis sed ut ex. Etiam blandit ante sed lacus ullamcorper pulvinar. Ut egestas massa a egestas accumsan. Etiam eu velit ornare, consectetur urna quis, cursus ex. Suspendisse et ipsum mauris. Praesent vestibulum metus ac quam laoreet accumsan. Sed quis ultrices massa, quis elementum nunc. Nam a massa varius lacus suscipit fringilla.'
        'Nulla ullamcorper euismod dui sit amet elementum. Suspendisse dapibus eu tellus eu placerat. Sed sit amet nisi ac lectus maximus convallis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam erat volutpat. Praesent vitae lacus ac dui aliquam vehicula et sed diam. In eget interdum erat. Donec vel ex quis mi ornare vulputate ut sit amet purus. Curabitur aliquet ornare turpis, sed luctus orci ultrices nec. Mauris vestibulum euismod arcu, eu mollis nulla fermentum eu. Donec sit amet nulla leo. Nam vitae justo nec magna egestas venenatis. Sed ut ipsum fermentum, fermentum est nec, laoreet mauris. Duis et suscipit libero, nec porttitor erat. Proin vel sem sollicitudin, hendrerit mauris ac, accumsan eros.'
        'Proin non egestas velit, in pharetra neque. Etiam a sapien in nunc cursus pharetra. Integer mi nunc, interdum volutpat mi molestie, eleifend consequat lorem. Etiam mattis in libero eget fringilla. Mauris aliquet libero non massa blandit auctor. Duis vestibulum velit dignissim nunc ullamcorper porttitor. Ut vestibulum, neque id blandit eleifend, lectus turpis consectetur nunc, id viverra mauris lacus vitae ipsum. Aliquam quis finibus risus. ',
    weapons: weapons,
    summary: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
  ),
  SeventeenHundredWars(
    imageUrl:
        'https://cdn.pixabay.com/photo/2017/11/24/05/38/jet-2974131_960_720.jpg',
    centuries: 1700,
    name: 'Anglo-Mysore Wars 1766–1799.',
    place: 'India',
    howManyDied: 20000,
    description:
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla odio ipsum, rhoncus id libero id, pretium congue sem. Nunc vitae ultricies justo. In ac nunc a ligula lobortis mattis sed ut ex. Etiam blandit ante sed lacus ullamcorper pulvinar. Ut egestas massa a egestas accumsan. Etiam eu velit ornare, consectetur urna quis, cursus ex. Suspendisse et ipsum mauris. Praesent vestibulum metus ac quam laoreet accumsan. Sed quis ultrices massa, quis elementum nunc. Nam a massa varius lacus suscipit fringilla.'
        'Nulla ullamcorper euismod dui sit amet elementum. Suspendisse dapibus eu tellus eu placerat. Sed sit amet nisi ac lectus maximus convallis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam erat volutpat. Praesent vitae lacus ac dui aliquam vehicula et sed diam. In eget interdum erat. Donec vel ex quis mi ornare vulputate ut sit amet purus. Curabitur aliquet ornare turpis, sed luctus orci ultrices nec. Mauris vestibulum euismod arcu, eu mollis nulla fermentum eu. Donec sit amet nulla leo. Nam vitae justo nec magna egestas venenatis. Sed ut ipsum fermentum, fermentum est nec, laoreet mauris. Duis et suscipit libero, nec porttitor erat. Proin vel sem sollicitudin, hendrerit mauris ac, accumsan eros.'
        'Proin non egestas velit, in pharetra neque. Etiam a sapien in nunc cursus pharetra. Integer mi nunc, interdum volutpat mi molestie, eleifend consequat lorem. Etiam mattis in libero eget fringilla. Mauris aliquet libero non massa blandit auctor. Duis vestibulum velit dignissim nunc ullamcorper porttitor. Ut vestibulum, neque id blandit eleifend, lectus turpis consectetur nunc, id viverra mauris lacus vitae ipsum. Aliquam quis finibus risus. ',
    weapons: weapons,
    summary: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
  ),
  SeventeenHundredWars(
    imageUrl:
        'https://cdn.pixabay.com/photo/2014/06/21/21/57/apocalyptic-374208_960_720.jpg',
    centuries: 1700,
    name: 'American Revolutionary War 1775–1783.',
    place: 'US',
    howManyDied: 50000,
    description:
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla odio ipsum, rhoncus id libero id, pretium congue sem. Nunc vitae ultricies justo. In ac nunc a ligula lobortis mattis sed ut ex. Etiam blandit ante sed lacus ullamcorper pulvinar. Ut egestas massa a egestas accumsan. Etiam eu velit ornare, consectetur urna quis, cursus ex. Suspendisse et ipsum mauris. Praesent vestibulum metus ac quam laoreet accumsan. Sed quis ultrices massa, quis elementum nunc. Nam a massa varius lacus suscipit fringilla.'
        'Nulla ullamcorper euismod dui sit amet elementum. Suspendisse dapibus eu tellus eu placerat. Sed sit amet nisi ac lectus maximus convallis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam erat volutpat. Praesent vitae lacus ac dui aliquam vehicula et sed diam. In eget interdum erat. Donec vel ex quis mi ornare vulputate ut sit amet purus. Curabitur aliquet ornare turpis, sed luctus orci ultrices nec. Mauris vestibulum euismod arcu, eu mollis nulla fermentum eu. Donec sit amet nulla leo. Nam vitae justo nec magna egestas venenatis. Sed ut ipsum fermentum, fermentum est nec, laoreet mauris. Duis et suscipit libero, nec porttitor erat. Proin vel sem sollicitudin, hendrerit mauris ac, accumsan eros.'
        'Proin non egestas velit, in pharetra neque. Etiam a sapien in nunc cursus pharetra. Integer mi nunc, interdum volutpat mi molestie, eleifend consequat lorem. Etiam mattis in libero eget fringilla. Mauris aliquet libero non massa blandit auctor. Duis vestibulum velit dignissim nunc ullamcorper porttitor. Ut vestibulum, neque id blandit eleifend, lectus turpis consectetur nunc, id viverra mauris lacus vitae ipsum. Aliquam quis finibus risus. ',
    weapons: weapons,
    summary: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
  ),
];

Now you can write the content or you can use the dummy content as we see above.

To complete please clone the GitHub repository, in your local machine, and develop.

At the end of the project you will learn how to design a Flutter UI.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

Leave a Reply