Flutter app demo, using Material theme

First Flutter Demo by alfred, there are multiple demo in it. This is my first Flutter Demo code, which contains multiple demos.

Login/SignUp

have 3 screens. First screen is a welcome screen for user to choose login or sign up.At welcome screen if user hit the login button the will shifts to the login screen,otherwise it will shifts user to the sign up screen. There are three interfaces . The first interface is a welcome interface, where users can choose to log in or register. If the user clicks the login button, it will jump to the login interface, otherwise it will jump to the registration interface.

EShop

have 2 screens. First you will see a goods list, when user hit the goods item, it will shifts to detail screen by hero animation. There are two interfaces. The first entry is the product list page. When the user clicks on the product, it jumps to the product details page. Demo uses Hero animation.

Movie App

have 2 screens. First you will see a movie list that only contains 3 movies.User can switch the card to check other movies.when user hit the card it will shifts to the detail screen that show more information about the movie. There are two interface. The first entry is the product list page. When the user clicks on the product, it jumps to the product details page. Demo uses Hero animation.

install Flutter on Mac

  1. Open Terminal
  2. Get SDK from https://github.com/flutter/flutter.git
  3. run the following command to create and open .bash_profile
touch ~/.bash_profile
code ~/.bash_profile
  1. insert the following code to .bash_profile
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
export PATH= SDKPATH/bin:$PATH

the SDKPATH is your sdk path

  1. run the following code to set PATH variable to the current terminal.
source ~/.bash_profile
  1. run command code ~/.zshrc to open z shell config file. Then append command source ~/.bash_profile to .zshrc file. so the flutter will add to your path permanently.
  2. run command flutter doctor to check if there are any dependencies is not installed in your compute.According to the output describe, you will know how to perform these tasks.

Flutter environment deployment (MacBook)/

  1. Pull the SDK from https://github.com/flutter/flutter.git .

  2. Open terminal

  3. Run the following code to create and open the .bash_profile file.

touch ~/.bash_profile
code ~/.bash_profile
  1. Enter the following in Visual Studio Code:
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
export PATH= SDKPATH/bin:$PATH
  1. Where SDKPATH is the installation directory of SDK
  2. Run the following code to update the terminal environment variables
source ~/.bash_profile
  1. Run to code ~/.zshrcopen the terminal configuration file and enter source ~/.bash_profile. This will automatically help set environment variables every time you open the terminal.
  2. Run flutter doctorcheck environment is missing, and perform dependent installation according to the prompt statement.

Knowledge of components used

StatelessWidget

Stateless Widget. Once the parameters are passed, they cannot be changed. When there is no need to rely on the parent container, this Widget is preferred.

StatefulWidget

For a stateful Widget, you need to define a class that inherits from StateFulWidget, and the createState method must be rewritten in the class, which returns an instance of a class inherited from State. The interface can be dynamically rendered.

Scaffold

The official document realizes the most basic material design visual effects. Provides APIs for drawer menu, snack and sheet action. If you want to display the snackbar or sheet action, you need to obtain the ScaffoldState through Scaffold.of through the current context, and then call it through ScaffoldState.showSnackBar or scaffoldState.showBottomSheet.

Common attributes:

  • appBar(PreferredSizeWidget): AppBar settings
  • backgroundColor(Color): background color
  • body(Widget): body sub-content
  • bottomNavigationBar(Widget): bottom navigation bar
  • bottomSheet(Widget):Sheet Action
  • drawer(Widget): drawer
  • drawerDragStartBehavior(DragStartBehavior): drawer drag start behavior
  • drawerEdgeDragWidth(double): the width of the drawer from the edge
  • drawerEnableOpenDragGesture(bool): whether the drawer can be opened by edge gesture
  • floatingActionButton(Widget): floating button
  • floatingActionButtonAnimator(FloatingActionButtonAnimator): floating button animation
  • floatingActionButtonLocation(FloatingActionButtonLocation): floating button location

Container

The most common and commonly used containers can be combined with common drawing, positioning and customizing components.

The container first renders the padding, and then applies additional constraints (constraints) to the content that has been rendered with the padding (if the height and width settings are not empty, the height and width are merged into the constraints). Finally, the container will be wrapped in the blank content of the margin.

In the drawing process, the container first applies the incoming transform, then draws the background (decoration) based on padding, then draws its sub-content, and finally draws the foreground (foregroundDecoration) based on padding.

Containers without child content will be drawn as large as possible, unless configured or the size of the parent content is restricted (constraints). When constraints are configured, the container will be drawn as small as possible. If the container contains sub-content, it will be adjusted according to the size of the sub-content. Unless the width, height and constrain are configured in the constructor.

Common attributes:

  • alignment(AlignmentGeometry): the alignment method of sub-content
  • child(Widget): child content
  • color(Color): background color
  • constraints(BoxConstraints): restriction rules for sub-content
  • decoration(Decoration): background decoration of the container
  • foregroundDecoration(Decoration): foreground decoration of the container
  • margin(EdgeInsetsGeometry): outer margin
  • padding(EdgeInsetsGeometry): inner margin

Layout behavior: The container contains a number of other incompatible widgets and their incompatible layouts, so the layout behavior of the container will be a bit complicated. In short, the container tries to be ordered:

  • Rendering
  • Adjust your size based on sub-content
  • Rendering width and height
  • Restrict sub-content
  • Expand yourself to adapt to the parent container
  • As small as possible

More specific content such as:

  • If the component has no child content, no width and height, no restriction, and no restriction on its parent container, the container will be as small as possible.
  • If the component has no child content and no alignment method, but the width and height or constraints are set, the container will combine the constraints and the constraints of the parent container to be as small as possible.
  • If the component has no child content, no width and height, no constraints, no settings, but the parent container provides a constraint, the container is filled with the size of the parent container.
  • If the component is configured with its method and the parent container does not provide constraints, the container will resize to just wrap the child content.
  • If the component is configured with its way and the parent container is configured with constraints, the container will try to fill the parent container and arrange the child content according to its way.
  • Unless the component has a child content, but does not set the width, height, constraints, and its method, the container will apply the constraints of the parent container to the child content, and at the same time make the size of the container wrap the child content.
  • The margin and padding properties of the container also affect the layout.

Column

The official document displays his child nodes vertically. If you want the child nodes to divide the available height equally, you need to include the child content in the Expanded. At the same time, Column does not support scrolling. If you need to support scrolling, please use ListView. If there is only one sub-content, try to use Align or Center to control the display position of the sub-content.

Common attributes:

  • children([]): multiple child content
  • crossAxisAlignment(CrossAxisAlignment): cross alignment method
  • mainAxisAlignment(MainAxisAlignment): The way the main axis is aligned
  • mainAxisSize(MainAxisSize): main axis size limit

Note: If the in-line controls are not enough to display all the sub-contents, a yellow square and a red warning bar will be displayed on the right side of the Row container.

Row’s layout algorithm:

  1. Assign a Null or 0 flex parameter to each sub-content (non-Expended), which means that there is no height limit and the passed width limit. When crossAxisAlignment is set to stretch, the maximum width passed in is used as the width limit.
  2. According to the size set by the flex parameter, divide the remaining vertical space to the sub-content with flex
  3. Add all the vertical (height) constraints consistent with step 1 to the remaining sub-content. If the Flexible.fit property of the child content is FlexFit.tight, strict constraints are applied to fill the size allocated by the Column. If the Flexible.fit of the sub-content is FlexFit.loose, loose restrictions are applied and it is not mandatory to fill the size allocated by the Column.
  4. The width of the column is the maximum height of the child content.
  5. The height of the Column is specified by the mainAxisSize property. If mainAxisSize is MainAxisSize.Max, the width of Row is the maximum width of its parent; if mainAxisSize is MainAxisSize.Min, the width of Row is the sum of the width of its child content (not exceeding the width limit of Row’s parent)
  6. It is the mainAxisAlignment and crossAxisAlignment properties that determine the position of the child content.

Row

The official document displays its child nodes horizontally. If you want the child nodes to divide the available width equally, you need to include the child content in Expanded. At the same time, Row does not support scrolling. If you need to support scrolling, please use ListView. If there is only one sub-content, try to use the Align or Center component to control the display position of the sub-content.

Common attributes:

  • children([]): multiple child content
  • crossAxisAlignment(CrossAxisAlignment): cross alignment method
  • mainAxisAlignment(MainAxisAlignment): The way the main axis is aligned
  • mainAxisSize(MainAxisSize): main axis size limit

Note: If the in-line controls are not enough to display all the sub-contents, a yellow square and a red warning bar will be displayed on the right side of the Row container.

Row’s layout algorithm:

  1. Assign a Null or 0 flex parameter to each sub-content (non-Expended), which means that there is no width limit and the incoming height limit. When crossAxisAlignment is set to stretch, the maximum height passed in is used as the height limit.
  2. According to the size set by the flex parameter, split the remaining horizontal controls to the sub-content with flex set
  3. Add all the vertical (height) constraints consistent with step 1 to the remaining sub-content. If the Flexible.fit property of the child content is FlexFit.tight, strict constraints are applied to fill the size allocated by Row. If the Flexible.fit of the sub-content is FlexFit.loose, loose restrictions are applied and it is not mandatory to fill the size allocated by Row.
  4. The height of Row is the maximum height of the child content.
  5. The width of Row is specified by the mainAxisSize property. If mainAxisSize is MainAxisSize.Max, the width of Row is the maximum width of its parent; if mainAxisSize is MainAxisSize.Min, the width of Row is the sum of the width of its child content (not exceeding the width limit of Row’s parent)
  6. It is the mainAxisAlignment and crossAxisAlignment properties that determine the position of the child content.

Stack

Stack is a component that allows sub-content to be positioned relative to it. If you want to stack several components quickly, Stack is the most suitable. The sub-content of Stack is either positioned or non-positioned. The positioned sub-content is wrapped in the Positioned component, and at least one attribute is configured. The size of the Stack will wrap all non-positioned sub-content, and the non-positioned sub-content will be positioned according to the alignment property (default is top-left). The positioned sub-content will be positioned relative to the Stack based on top, left, bottom, and right. Stack will be rendered in stack order according to the order of children. If you want to change the order of children rendering, you can try to rearrange the order of children, and it is recommended to define a non-empty key for each child content. When a non-empty key is defined, flutter will move the corresponding child content to a new position when rearranging the order of the children, instead of recreating the child content in the new position. If you want to lay out multiple child content with a special template, or create a custom layout management, you may use CustomMultiChildLayout instead. In particular, when using Stack, you cannot locate the sub-content relative to the size of the sub-content or the number of Stack’s own children.

Common attributes:

  • children(List): child content array
  • alignment(AlignmentGeometry): alignment method
  • fit(StackFit): The size limit of non-positioned sub-content.
  • OverFlow (OverFlow): Display method of sub-content that exceeds the size of Stack
  • textDirection(TextDirection): Text rectangle

Stack layout algorithm:

GestureDetector

InkWell

It is a rectangular area used for touch operation of the corresponding Material Design. When the user clicks on the area of ​​InkWell, it will automatically render a MaterialDesign water ripple effect. The water ripple will not exceed the range of InkWell. If you don’t want to cut the water ripple effect, you can use InkResponse. The parent content of InkWell must have a Material component. The water ripple animation will actually be rendered in InkWell’s nearest Material parent content. (This is in line with the concept of Material Design). When using this component, you can call debugCheckHasMaterial(context) at the beginning of the Build function to check whether it is valid.

Common attributes:

  • borderRadius(BorderRadius): Water ripple border rounded corners
  • child(Widget): child content
  • radius(double): water ripple radiation size
  • splashColor(Color): water ripple color
  • containedInkWell(bool): Whether the water ripple can exceed the container
  • enableFeedback(bool): Whether there is a sound or vibration prompt when the interaction is detected
  • onTap(Function)
  • onHover(Function)
  • hoverColor(Color): the color of the Hover state

Icon

The official document is a graphical icon component, drawn according to the font icon information defined by IconData. You can use the Material style Icons built into flutter. Icon is not an interactive component. If you want to build an interactive Icon, it is recommended to use IconButton. Note: The rendering of non-square icons may be wrong.

Common attributes:

  • color(Color): icon color
  • icon(IconData): icon
  • semanticLabel(String): The description of the icon. Effective in obstacle mode.
  • size(double): size
  • textDirection (TextDirection): 方向

TextField

Official documentation This widget allows users to enter text. When the user modifies the content, the onChanged function will be called back. When the user indicates that the input is complete, the onSubmitted callback function will be called back. Most of the time onSubmitted is enough to handle the response to user input. When the user completes the input, the onEditingComplete callback function will also be called. Unlike onSubmitted, it will have a default behavior to update the text controller and terminate the keyboard focus.

If you want to control the content displayed in the TextField, you can use the controller attribute to specify a controller. The controller can not only display the content of the TextField, but also control the selection or style of the content. If you need to read the input value, you can also get it through controller.text. When the controller is no longer needed, dispose must be called.

By default in Material, the TextField will have a bottom border, which can be changed through the decoration property. If you want to inherit in the FormField component, use TextFormField first

Common attributes:

  • controller(TextEditingController):指定的controller
  • cursorColor(Color): cursor color
  • cursorRadius(Radius): the rounded corners of the cursor
  • cursorWidth(double): cursor width
  • decoration(InputDecoration): style formulation
  • enable(bool): enable/disable
  • expands(bool): Whether to fill the parent content highly
  • keyboardType(TextInputType): keyboard type
  • obscureText(bool): Whether to hide the input content
  • onChanged(Function): content input callback
  • onSubmitted(Function): content change callback
  • onTap(Function): click callback
  • readOnly(bool): read only
  • style(TextStyle): the style of the input content
  • textAlign (TextAlign): content alignment
  • textAlignVertical(TextAlignVertical): The way the content is aligned vertically
  • toolbarOptions(ToolbarOptions): custom toolbar

Text

The official document displays a single style of text, and the displayed text can be broken. When the style attribute is not defined, Text will use the DefaultTextStyle of the nearest parent content. If you set the TextStyle.inherit of style to true, the given style will be merged with the DefaultTextStyle of the nearest parent content.

Using the Text.rich constructor, Text can use TextSpan to display a paragraph of text with different formats. The RichText widget can also achieve the same effect.

If you want to interact through Text, you can wrap it in the GestureDetector component. However, in the application of MaterialDesign, it is recommended to use FlatButton parts instead. If FlatButton is not applicable, InkWell can be used instead of GestureDetector.

If you want to perform interactive operations on a certain part of a text, use the RichText component and assign TapGestureRecognized to the recognized property of the TextSpan that needs to be interacted.

Common attributes:

  • data(String): the displayed text
  • locale(Locale): localized configuration
  • maxLines(int): Maximum number of displayed lines
  • overflow(TextOverflow): the display method of text overflow
  • style(TextStyle): text style
  • textAlign (TextAlign): text alignment
  • textDirection(TextDirection): text display mode

Divider

SizedBox

The official document is a container of a specified size.

If the sub-content is defined, the sub-content will be forced to have the width and height of the SizedBox. If the SizedBox does not define the width and height, it will wrap the child content, but if the size of the child content depends on the size of the parent content, the size of the SizedBox must be provided. If there is no child content, SizedBox will try to match the size limit of the parent content.

If there is no width and height for SizedBox and no sub-content, the default width and height will be 0.

The constructor of SizedBox.expand can construct a SizedBox whose width and height match the parent content. The effect is equivalent to setting Width and Height to double.infinity.

Common attributes:

  • height(double)
  • width(double)
  • child(Widget)

Navigator

SingleChildScrollView

Hero

FloatingActionButton

RaisedButton

Official document

AspectRatio

PageController

PageView

Download Details:

Author: McPorkChop

Source Code: https://github.com/McPorkChop/AlfredFirstFlutterMaterialApp

#flutter #dart #mobile-apps

Flutter app demo, using Material theme
2.15 GEEK