Flutter from entry to collapse (I) : A login interface

Remember before

There are currently three approaches to cross-platform development: ReactNative,Weex, and Flutter. As for the differences between them and how to choose one or the other, I think this is already discussed in the mobile engineer community. Never!!!!! 10 million!! Don’t try to think you can step out of the weex hole. Conclusion, let’s begin to touch Flutter! Flutter is Google dad’s next generation development voice. It features both ios and Android, but not only that, Flutter is also the designated development tool for the next generation of Google Dad’s operating system. As android 🐶, it is always right to follow Google Dad. Weex these ES6 guys, get into dart’s arms (not because I hate JS and CSS).

Learning indicators

Because I’m lazy… And I am project-driven lazy ghost, my way of learning can be summarized as: do project + step pit + fill pit + step pit + fill pit… + Curse = Master a knowledge so let’s make a project with Flutter!

Environment set up

According to the official website tutorial can be, a few days LATER I will write a detailed point

Basic introduction to

I’m not very basic… I’ll tell you more when I’m clear

Weight is introduced

Same as above

The realization of the login interface

Page logic explanation

We can see that the page is concise:

  • A logo
  • An account entry box
  • A password entry box
  • A login button

Now let’s disassemble the page:

  1. AppBar
  2. Body
    1. Account box
    2. The password
    3. The login button

As you can see, the page is divided into two main layers: the top layer (only at the top of the code hierarchy, not including layers like Windows) is AppBar(title bar) and Body(Body bar), which contains the secondary widgets

The specific implementation

We’ll post the code first and then explain it in detail

import 'package:flutter/material.dart';

class LoginPage extends StatefulWidget {

  @override
  State<StatefulWidget> createState() {
    return new_LoginPageState(); }}class _LoginPageState extends State<LoginPage> {
  var leftRightPadding = 30.0;
  var topBottomPadding = 4.0;
  var textTips = new TextStyle(fontSize: 16.0, color: Colors.black);
  var hintTips = new TextStyle(fontSize: 15.0, color: Colors.black26);
  static const LOGO = "images/oschina.png";

  var _userPassController = new TextEditingController();
  var _userNameController = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Login", style: new TextStyle(color: Colors.white)),
          iconTheme: new IconThemeData(color: Colors.white),
        ),
        body: new Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            new Padding(
              padding: new EdgeInsets.fromLTRB(
                  leftRightPadding, 50.0, leftRightPadding, 10.0),
              child: new Image.asset(LOGO),
            ),
            new Padding(
              padding: new EdgeInsets.fromLTRB(
                  leftRightPadding, 50.0, leftRightPadding, topBottomPadding),
              child: new TextField(
                style: hintTips,
                controller: _userNameController,
                decoration: new InputDecoration(hintText: "Please enter user name"),
                obscureText: true,),),new Padding(
              padding: new EdgeInsets.fromLTRB(
                  leftRightPadding, 30.0, leftRightPadding, topBottomPadding),
              child: new TextField(
                style: hintTips,
                controller: _userPassController,
                decoration: new InputDecoration(hintText: "Please enter user password"),
                obscureText: true,),),new Container(
              width: 360.0,
              margin: new EdgeInsets.fromLTRB(10.0.40.0.10.0.0.0),
              padding: new EdgeInsets.fromLTRB(leftRightPadding,
                  topBottomPadding, leftRightPadding, topBottomPadding),
              child: new Card(
                color: Colors.green,
                elevation: 6.0,
                child: new FlatButton(
                    onPressed: () {
                      print("the pass is" + _userNameController.text);
                    },
                    child: new Padding(
                      padding: new EdgeInsets.all(10.0),
                      child: new Text(
                        'Log in now',
                        style:
                            new TextStyle(color: Colors.white, fontSize: 16.0),),),),),)); }}Copy the code

Now we can see the whole layout, how to say… For someone who is used to writing Android, this code style is really not comfortable, especially string upon string),))),]})}, and to be honest, I miss XML, and even Kotlin.

The basis of the entire page

Because the needs of the page change, we use **StatefulWidget **, and the difference between *StatefulWidget and StatelessWidget * is described in my previous post. In the State build method, we start building the page:

@override
  Widget build(BuildContext context) {
	  return new Scaffold(
			appBar:new AppBar(),
			body:new Column(),
		)
  }
Copy the code

Where AppBar puts navigation information, Body puts Body information,

Build of the body child widgets

 body: new Column(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            new Padding(
              padding: new EdgeInsets.fromLTRB(
                  leftRightPadding, 50.0, leftRightPadding, 10.0),
              child: new Image.asset(LOGO),
            ),
            new Padding(
              padding: new EdgeInsets.fromLTRB(
                  leftRightPadding, 50.0, leftRightPadding, topBottomPadding),
              child: new TextField(
                style: hintTips,
                controller: _userNameController,
                decoration: new InputDecoration(hintText: "Please enter user name"),
                obscureText: true,),),new Padding(
              padding: new EdgeInsets.fromLTRB(
                  leftRightPadding, 30.0, leftRightPadding, topBottomPadding),
              child: new TextField(
                style: hintTips,
                controller: _userPassController,
                decoration: new InputDecoration(hintText: "Please enter user password"),
                obscureText: true,),),new Container(
              width: 360.0,
              margin: new EdgeInsets.fromLTRB(10.0.40.0.10.0.0.0),
              padding: new EdgeInsets.fromLTRB(leftRightPadding,
                  topBottomPadding, leftRightPadding, topBottomPadding),
              child: new Card(
                color: Colors.green,
                elevation: 6.0,
                child: new FlatButton(
                    onPressed: () {
                      print("the pass is" + _userNameController.text);
                    },
                    child: new Padding(
                      padding: new EdgeInsets.all(10.0),
                      child: new Text(
                        'Log in now',
                        style:
                            new TextStyle(color: Colors.white, fontSize: 16.0),),),),),));Copy the code

The layout looks terrible… Now I miss XML again… From the top to the bottom of the page, LET me comb it out in plain English:

  1. A multilayout parent control with a list of child Widgets in a numeric arrangement of the parent layout, arranged from the beginning
  2. The first child is an IMG Widgets, which is wrapped around the Padding Widgets so that it can get the padding properties
  3. The second child is a TextFidld widget (Android guys can think of it as EditText), which is also wrapped in the Padding Widgets, providing the padding on four sides, It also sets hints via InputDecoration and controllers via Controller
  4. The third child Widgets should, in theory, extract public methods, and the second and third should not be copied over
  5. The fourth widget is a FlatButton(there are actually two Widgets wrapped around it). It gets the padding and margin properties by being wrapped around the Container. I get the shadow property by being wrapped by card.

So far the layout is finished, sum up: the first time to write feel very troublesome, especially troublesome! ({{{}}}}){{{}}} Digging grass, crazy. Life ah, can not resist, you QJ ME fifth time write feel… Yi, with the feeling of a little bit excited to write the sixth time feel, seems to be quite convenient… . For the NTH time, cool! I don’t want XML.

Page interaction

There are not many interactions on this page, no more than two:

  1. Get the value of TextField
  2. Corresponding FlatButton click

B: well… I can’t find my id, also can not find the findViewById, also can not find the String mAccount = mEdLoginAccout. The getText. ToString ()… Rush toward street…

But remember that TexditingController we just defined? Manipulating a TextField is usually done by manipulating a Controller, but the simplest and most common one is

TextEditingController.text
/ / equal EditText getText ()
Copy the code

And the click event can be onPressed()

 onPressed: () {
     print("the pass is" + _userNameController.text);
	            },
Copy the code

conclusion

  1. Carelessly water again one, have no what dry goods, because I also be a beginner, learn while record
  2. Flutter is nice, at least not rendered like Weex. I’m optimistic that rn and Weex don’t have a particularly good experience
  3. The Flutter listview got stuck on my MX5. I don’t know if I didn’t optimize the code or what… I’ll mark with this question in mind
  4. Dry dad