introduce

I recently learned about the use of some of the Flutter controls and saw a nice login screen on Github, so I tried to mimic them myself. The original author did a nice job, but just implemented the interface. So I add things myself, like the use of keys and the use of inheritedWidgets.

Here are some summaries. If there are any mistakes, please point them out. Thank you.

The final display interface

The code structure

The main control used

  1. Use Row, Column to arrange sublayouts horizontally or vertically
  2. Stacking is realized by Stack, and absolute positioning is realized by the positioning control
  3. Use Containers for decorative effects
  4. TextFormField is used to implement text input, and Form is used to manage these TextFormFields
  5. Use keys to get the state of the widget
  6. Use inheritedWidgets to pass data to child controls
  7. Using PageView and PageController page sliding switch

Add dependencies in pubspec.yaml

  1. Font_awesome_flutter, this is a library of Flutter ICONS
  2. Add a top image of the login screen and declare the resource path. Instead of declaring resources one by one, the following script imports the entire folder of resources into the application.
  3. Random_pk. Here’s what this library does. On the one hand, it provides random colors for the container. On the other hand, I think we can debug the layout with a Container with color. The RandomContainer is used the same way as Container, just wrapping the Child. Then you can use the size of the container background to determine whether the layout is the right size. It looks more intuitive, and you don’t need to manually write container+color. Remove the layer of RandomContainer when you don’t need it. When I use myself at ordinary times, discover really quite effective, everybody can take try.
Random_pk: any font_awesome_flutter: any // omit some code assets: -assets /Copy the code

Code implementation

Ejbateful interface interface interface interface interface interface interface interface interface interface interface interface interface interface interface

class LoginPage extends StatefulWidget {
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  @override
  Widget build(BuildContext context) {
    returnContainer(); }}Copy the code

2. Write code according to the layout

This part is nothing to say, mainly to be familiar with the use of some controls, according to the UI draft step by step to write the layout can be.

For example, an implementation of TextForm for entering an account and password

/** * Create a TextForm */ Widget for the login interfacebuildSignInTextForm() {
    returnnew Container( decoration: new BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(8)) , color: Color.white), width: 300, height: 190, /** * Flutter provides a Form widget that groups input fields * and then performs uniform operations such as input validation, input field resetting, and input saving. */ child: new Form( key: _SignInFormKey, // Enable automatic validation of input content. Otherwise, every time you modify the child's TextFormField, other textFormfields will also be validated.true, child: new Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ Flexible( child: Padding( padding: Const EdgeInsets. Only (left: 25, right: 25, top: 20, bottom: 20), child: new TextFormField(// Associated focus focusNode: emailFocusNode, onEditingComplete: () {if (focusScopeNode == null) {
                      focusScopeNode = FocusScope.of(context);
                    }
                    focusScopeNode.requestFocus(passwordFocusNode);
                  },

                  decoration: new InputDecoration(
                      icon: new Icon(Icons.email, color: Colors.black,),
                      hintText: "Email Address", border: InputBorder. None), style: new TextStyle(fontSize: 16, color: color.black), // Validator: (value) {if (value.isEmpty) {
                      return "Email can not be empty!";
                    }
                  },
                  onSaved: (value) {

                  },
                ),
              ),
            ),
            new Container(
              height: 1,
              width: 250,
              color: Colors.grey[400],
            ),
            Flexible(
              child: Padding(
                padding: const EdgeInsets.only(
                    left: 25, right: 25, top: 20),
                child: new TextFormField(
                  focusNode: passwordFocusNode,
                  decoration: new InputDecoration(
                      icon: new Icon(Icons.lock, color: Colors.black,),
                      hintText: "Password", border: InputBorder.none, suffixIcon: new IconButton(icon: new Icon( Icons.remove_red_eye, color: Color.black,), onPressed: showPassWord), // enter the password with ***** to display obscureText:! isShowPassWord, style: new TextStyle(fontSize: 16, color: Colors.black), validator: (value) {if (value == null || value.isEmpty || value.length < 6) {
                      return "Password'length must longer than 6!";
                    }
                  },
                  onSaved: (value) {

                  },
                ),
              ),
            ),


          ],
        ),),
    );
  }
Copy the code

For example, the implementation of PageView

PageController _pageController;
  PageView _pageView;
  int _currentPage = 0;

  @override
  void initState() {
    super.initState();
    _pageController = new PageController();
    _pageView = new PageView(
      controller: _pageController,
      children: <Widget>[
        new SignInPage(),
        new SignUpPage(),
      ],
      onPageChanged: (index) {
        setState(() { _currentPage = index; }); }); }Copy the code

3. Use of inheritedWidgets

For example, if I want a child control in any place and I want to get the User’s data User, I can use the InheritedWidget to do that. If we use Theme. Of (context) to get the app’s Theme anywhere, or mediaQuery.of (context) to get the app’s screen data, we’re essentially using inheritedWidgets to share the data.

I will write an article to explain the specific usage.

When the InheritedWidget is rebuilt, the didChangeDependencies() interface */ class UserProvider is triggered  extends InheritedWidget { final Widget child; final User user; UserProvider({this.user, this.child}) : super(child: child); UserProvider({this.user, this.child}) : super(child: child); /* override bool updateShouldNotify(InheritedWidget oldWidget) {return true; }} /** * Requires a StatefulWidget as the outer component, */ class UserContainer extends StatefulWidget {// Data shared with child controls final User User; final Widget child; UserContainer({Key key, this.user, this.child}) : super(key: key); @override _UserContainerState createState() => _UserContainerState(); static UserProvider of(BuildContext context) {return context.inheritFromWidgetOfExactType(UserProvider);
  }
}

class _UserContainerState extends State<UserContainer> {
  @override
  Widget build(BuildContext context) {
    returnnew UserProvider(user: widget.user, child: widget.child); }}Copy the code

4. The use of the Key

In Flutter, each Widget build method has an optional key parameter. If no key is passed, the application automatically generates a key. This key value is unique throughout the application, and a key is unique to a widget, so you can use the key to obtain the state of the widget and control the widget.

For example, I use the key to get the Form state. When I click on the login button, I use the key to get the widget state. Then I use the Form state to operate the Form’s descendant FromField uniformly.

// Define a key and associate it with the corresponding widget GlobalKey<FormState> _SignInFormKey = new GlobalKey(); new Form( key: _SignInFormKey, child: .........)Copy the code
FormState can be used to manipulate the Form's descendant FromField */if(_SignInFormKey. CurrentState. The validate ()) {/ / if the input is inspection by log in Scaffold. The operation of (context). ShowSnackBar (new SnackBar (the content: new Text("Perform login operation"))); / / call all the children of the save the callback, save the form contents _SignInFormKey. CurrentState. The save (); }Copy the code

Problems encountered

1. Some layout holes utilize SafeArea to display content in safe visible areas. Use SingleChildScrollView to avoid overFlow when the keyboard pops up.

2. Understand the concepts and relationships between context, state, key, and widget. This article is well written: p1-jj.byteimg.com/tos-cn-i-t2…

Next step

Continue to sort out my gains and problems in learning Flutter

Demo address (code I have added a lot of comments)

Github.com/LXD31256949…