Read the advice

  • Word count: 2739
  • Timing: It depends on you
  • Main contents: pictures, codes have
  • Scene: On the way to work, in bed
  • Chapter 2 Portal: The Practical Application of Flutter From scratch an “island” APP (No.2, Splash Page, boot Page)

Chapter objectives

We’re going to finish that

Since we are the requested network image resources, there will be some request time, but also to optimize

Writing in the front

Before embarking on this journey of Flutter, you need to reserve some common points

  • Sciencenet: Don’t ask why, because this step is particularly important as a development step
  • Wendux, AUTHOR of The Practical Application of Flutter: This book is suitable for the novice to get a preliminary understanding of the various parts of Flutter. This will be different from our HTML
  • There will be some video resources and plugin recommendations for Flutter
  • As we all know, Xianyu and other apps are developed with the application of Flutter technology in China, and their contribution to the Flutter family is particularly important.

This is the first part of this journey, because I do not know what progress will be developed, but try to update one every week, let us learn together, lets_do_it

Project initialization

So since we are going to start a new project, we choose to initialize a new project. I can find anywhere on the disk, so I’m going to choose this one

Project catalog

Once the project is created, the usual routine is to remove useless code, the main one being main.dart

Here we can set the virtual machine hierarchy for easy debugging

Always open this on the top

The directory structure

Start creating some folders that you can see by name

  • Models is basically the Model class that holds the project. Why is it not good for us to directly manipulate the JSON returned in the background in the project
  • Pages is mainly to place some page files, including home page, book list, like
  • Provider places global state management
  • The common method classes in the utils project
  • Widgets Common widgets

Depend on the installation

We can try bookmarking these two urls

  • Pub some third-party plug-ins and packages will also be used in our project
  • Hub includes excellent projects like Flutter-go. I heard that appID users can apply for application of APP through official channels
The plug-in name address
flutter_screenutil flutter_screenutil Screen adaptation
curved_navigation_bar curved_navigation_bar Bottom navigation bar
provider provider State management
shared_preferences shared_preferences Local persistence
dio dio Network request
fluro fluro Routing framework
.

Master file parsing

We’ve already initialized the project up there, and obviously a black color is a little bit ugly, not our aesthetic, look at the MaterialApp

Exposed apis

  const MaterialApp({
    Key key,
    this.navigatorKey,
    this.home, 
    this.routes = const <String, WidgetBuilder>{},
    this.initialRoute,
    this.onGenerateRoute,
    this.onUnknownRoute,
    this.navigatorObservers = const <NavigatorObserver>[],
    this.builder,
    this.title = ' '.this.onGenerateTitle,
    this.color,
    this.theme,
    this.darkTheme,
    this.themeMode = ThemeMode.system,
    this.locale,
    this.localizationsDelegates,
    this.localeListResolutionCallback,
    this.localeResolutionCallback,
    this.supportedLocales = const <Locale>[Locale('en'.'US')].this.debugShowMaterialGrid = false.this.showPerformanceOverlay = false.this.checkerboardRasterCacheImages = false.this.checkerboardOffscreenLayers = false.this.showSemanticsDebugger = false.this.debugShowCheckedModeBanner = true.Copy the code
  • Home should be the home page
  • InitialRoute is not an initialRoute, maybe we can use it later when we write the route
  • Title should be the title
  • Color color
  • Theme B

In our impression, an APP is divided into upper, middle and lower parts, just like our human head, body and feet

So let’s start writing my first page

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

void main() => runApp(MyApp());

// Here we use the StatelessWidget, I am a stateless "child"
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'island', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHome(), ); }}class MyHome extends StatefulWidget {
  MyHome({Key key}) : super(key: key);

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

class _MyHomeState extends State<MyHome> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('island APP'),),); }}Copy the code

Obviously, if we put all these components in the same folder, it is not in line with the development specifications, and is not conducive to the later optimization and maintenance.

Put it in the Pages folder

Lib ├ ─ ─ pages ├ ─ ─ ─ ─ book_list_page. Dart ├ ─ ─ ─ ─ home_page. Dart ├ ─ ─ ─ ─ love_page. The dartCopy the code

The initial code for each page looks like this

  • book_list_page.dart
import 'package:flutter/material.dart';

class BookListPage extends StatefulWidget {
  BookListPage({Key key}) : super(key: key);

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

class _BookListPageState extends State<BookListPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('I'm a book list'),),); }}Copy the code
  • home_page.dart
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);

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

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('I am the home page'),),); }}Copy the code
  • love_page.dart
import 'package:flutter/material.dart';

class LovePage extends StatefulWidget {
  LovePage({Key key}) : super(key: key);

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

class _LovePageState extends State<LovePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('I do.'),),); }}Copy the code

Bottom navigation bottomNavigationBar

Here we use the **curved_navigation_bar ** wheel

First, add dependencies

dependencies:
  curved_navigation_bar: ^0.31. #latest version
Copy the code

Earlier, we said that we put some common widgets in the widgets file, so we’re going to put them in the common widgets folder and call it widget_bottom_navigation_bar.dart

Introduced at the head of the file

import 'package:flutter/material.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';

import '.. /pages/home_page.dart';
import '.. /pages/book_list_page.dart';
import '.. /pages/love_page.dart';
Copy the code

The entire code is


/// here we are living a stateful component, because index changes are involved
class BottomNavBarWidget extends StatefulWidget {
  BottomNavBarWidget({Key key}) : super(key: key);

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

class _BottomNavBarWidgetState extends State<BottomNavBarWidget>
    with SingleTickerProviderStateMixin {
  A controller is declared here. There are many uses for controllers in Flutter, including the most common forms
  TabController tabController;

  /// put the three pages we introduced into the List collection and wait for it to happen
  List _pages = [HomePage(), BookListPage(), LovePage()];

  /// this is the core index, the default value is our home page
  int currentIndex = 0;

  @override
  void initState() {
    super.initState();
    tabController = TabController(vsync: this, length: 3)
      ..addListener(() {
        /// setState is a bit like React, when changing data, it is in setState()
        setState(() {
          currentIndex = tabController.index;
        });
      });
  }

  // The Widget that returns the value type is the Widget that is the core of the interface
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        bottomNavigationBar: CurvedNavigationBar(
          // backgroundColor: _pages[currentIndex],
          index: currentIndex,
          // Bottom button
          items: <Widget>[
            Image.asset(
              'images/bottom_nav/[email protected]',
              width: 50,
              height: 50,
            ),
            Image.asset(
              'images/bottom_nav/[email protected]',
              width: 50,
              height: 50,
            ),
            Image.asset(
              'images/bottom_nav/[email protected]',
              width: 50,
              height: 50,)],/// Click the different bottom navigation
          onTap: (index) {
            //Handle button tap
            setState(() {
              currentIndex = index;
            });
            tabController.animateTo(index,
                duration: Duration(milliseconds: 300), curve: Curves.ease); },),// The body part is the same as the human body
        body: TabBarView(
          controller: tabController,
          children: <Widget>[
            Container(
              child: _pages[0],
            ),
            Container(
              child: _pages[1],
            ),
            Container(
              child: _pages[2]],)); }}Copy the code

As for how the wheel works, whether it’s a string or a widget, there’s nothing better than looking at the source code

  • Project: List of widgets
  • Index: The NavigationBar index, which can be used to change the current index or set the initial index
  • Color: The color of NavigationBar, which is colors.white by default
  • ButtonBackgroundColor: floating buttonBackgroundColor, default with color property
  • BackgroundColor: Background of NavigationBar, default Colors. BlueAccent
  • OnTap: Function handles clicks on items
  • AnimationCurve: Curve interpolation button changes animation, default Curves. EaseOutCubic
  • AnimationDuration: The button changes the Duration of the animation, default Duration (ms: 600)
  • Height: The height of the NavigationBar, minimum value 0.0, maximum 75.0

Local image import

It is necessary to study together the pictures we introduced above

 Image.asset(
              'images/bottom_nav/[email protected]',
              width: 50,
              height: 50,),Copy the code

Is the images/bottom_nav/[email protected],

  • Create an images directory under the project root and copy the images you want to this directory

  • Add the following to the flutter section of pubspec.yaml:

      assets:
        - images/bottom_nav/home@light.png
        - images/bottom_nav/book_list@light.png
        - images/bottom_nav/love@light.png
    Copy the code
  • Load the image

    • Image(
        image: AssetImage("images/avatar.png"),
        width: 100.0
      );
      Copy the code
    • Image.asset("images/avatar.png",
        width: 100.0.)Copy the code

So far, we’ve been working on some of them, and we haven’t had any bumps in the road, so this is what The Island APP looks like

Screen adaptation

When you click on the bottom navigation, you can switch between three pages. Now there’s a very important issue to consider. Let’s focus on the font at the head. So you need screens that don’t work

Here we use flutter_ScreenUtil

The Flutter screen adaptation solution allows your UI to display a reasonable layout on different screen sizes!

  • Packet address [flutter_ScreenUtil (github.com/OpenFlutter…)
  • The stars are 1.2 K +

How do you use it first

  • Width width ScreenUtil. GetInstance (). SetWidth (540).
  • Height height ScreenUtil. GetInstance (). SetHeight (200).
  • FontSize fontSize
// rectangle:
Container(
           width: ScreenUtil.getInstance().setWidth(375),
           height: ScreenUtil.getInstance().setHeight(200),),// If you want to display a square:
Container(
           width: ScreenUtil.getInstance().setWidth(300),
           height: ScreenUtil.getInstance().setWidth(300),),Copy the code
// The font size is passed in, which does not scale according to the system's "font size" helper by default (allowFontScaling can be set when ScreenUtil is initialized)
ScreenUtil.getInstance().setSp(28)         
 
// Pass in the font size to scale according to the system's "font size" helper (if a place does not follow the global allowFontScaling setting)
ScreenUtil(allowFontScaling: true).setSp(28)   
Copy the code

Import files that need to be adapted

import 'package:flutter_screenutil/flutter_screenutil.dart';
Copy the code

Note here that we write the sizing initialization at the bottom of the navigation

Next we screen fit the bottom three images

    items: <Widget>[
            Image.asset(
              'images/bottom_nav/[email protected]',
              width: ScreenUtil.getInstance().setWidth(100),
              height: ScreenUtil.getInstance().setHeight(100),
            ),
            Image.asset('images/bottom_nav/[email protected]',
                width: ScreenUtil.getInstance().setWidth(100),
                height: ScreenUtil.getInstance().setHeight(100)),
            Image.asset('images/bottom_nav/[email protected]',
                width: ScreenUtil.getInstance().setWidth(100),
                height: ScreenUtil.getInstance().setHeight(100)),,Copy the code

Now we need to do something about the font in the head, don’t we?

  • The introduction of the import ‘package: flutter_screenutil/flutter_screenutil. Dart’;
  • Specific adaptation
 title: Text(
        'I am the home page',
        style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(36))),Copy the code

I think there’s something inside

DEBUG in the upper right corner

In MaterialApp, debugShowCheckdModeBanner set to false

How to remove the Debug label in the Flutter app

At the end of this journey, let’s polish the Island.

    return Scaffold(
      appBar: AppBar(
        centerTitle: true,
        title: Text(
          'home',
          style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(36)),
        ),
      ),
      body: Container(
        height: ScreenUtil.getInstance().setHeight(1334),
        width: ScreenUtil.getInstance().setWidth(750),
        child: Image.network(
          'https://i.demo-1s.com/2019/11/16/yjhPSQWjuqPmosIL.jpg',
          fit: BoxFit.cover,
        ),
      ),
    );
Copy the code

Write in the last

This section of the road, we will go here together, the author will continue to update, please pay more attention to, the relevant code will also be synchronized to the author’s warehouse, github.com/yayxs/flutt…

If you like, might as well give an encouragement, well this young refueling ~~

END

Tips: Some ideas have learned from some excellent blog, such as improper, can also go to the author site message thank open source, thank you