Flutter Development Notes (a)

 

Recently doing the project, I would like to develop some components integrated Flutter. So began the road to the development of hybrid research Flutter. Welcome to the Dart camp.

Skip all the parts for installation and operation Flutter application directly to do if you are not sure what Flutter yes, and there are many problems, please read the road on the evolution of Flutter.

Dart

If you think Kotlin is an alternative to Java, wait until you see the Dart, you will find that it is straightforward, no boilerplate code:

  • The default is public, "_" privatization by the prefix;

  • Collection; click on probation

  • Everything is an object - not "primitives"

  • Named parameters, optional parameters, the default values: Click trial

  • Properties - without having to write "get" method anywhere

  • Cascade - everything Builders

  • Use strong mode type inference - just write "var" in the local

  • Named Constructor, automatically assigned to the field; click on probation

  • String interpolation, several types of string; click on probation

  • dartfmt - If you do not want to be without this tool to format

Here is an example code Dart, a private IP address obtaining method:

_getIPAddress() async {
    String url = 'https://httpbin.org/ip';
    var httpClient = createHttpClient();
    var response = await httpClient.read(url);
    Map data = JSON.decode(response);
    String ip = data['origin'];
}

Design Patterns

I'm sure you have your skills extend from disorder Android code to the MVC, MVP, MVVM, Dagger2, DataBinding and Android architecture components, Flutter is basically a V (View), responsive view, it can be stateless or there are state of the widget, even AppCompatActivity also a widget.

Let's create a very simple Activity, we need a text view and a button to update the text, the following is Activity Code (note that no XML):

public class Click extends Activity {
    int count = 0;
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.main);
        final Button button = (Button) findViewById(R.id.button);
        final TextView text = (TextView) findViewById(R.id.counter);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                count++;
                text.setText("Button clicked " + counter + " times");
            }
        });
    }
}

In Flutter, you do not need to manipulate the view, as the code () in the setText, you can instead use state, and will handle Flutter screen updates, and Flutter in the above code is equivalent to:

import 'package:flutter/material.dart';class Activity extends StatefulWidget {
  @override
  ActivityState createState() => new ActivityState();
}class ActivityState extends State<Activity> {
  int counter = 0;
  @override
  Widget build(BuildContext context) {    
      return new Scaffold(
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[            new Text(
              'Button clicked ${counter} times',
            ),            new FlatButton(
              child: new Text('Increment'),
              onPressed: () {
                setState(() {
                  counter++;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}

You also note that we have increased the value of the counter in setState, once onPressed is triggered (after a setState), Flutter will use the new counter value to re-render the entire widget and text objects.

The biggest advantage of the separation widget and state (for Android developers) is that if you rotate the device in Java code or resize the window (to support multi-window), then the value of the counter will be reset to zero, you have to write a lot repeat code to manage the life cycle of Activity. In Flutter, this is not required, the existing functionality with no additional code.

Although Dart eventually compiled to native code, but it does not access the hardware device, for example, if you want to get the user's location, you must use the  platform to  channel coding platform-specific, meanwhile, does have a lot of plug-ins to handle these situations, but you still want to sign in Android Studio (or Xcode) to complete the matter between code.

Async/Await

In Android development, UI thread is very important to complete the work at a slower pace of things, displays the following mysterious lines:

I/Choreographer(1378): Skipped 55 frames!  The application may be doing too much work on its main thread.

In this case you can only use threads to handle, as shown below:

public void onClick(View v) {
    new Thread(new Runnable() {
        public void run() {
            // a potentially  time consuming task
            final Bitmap bitmap =
                    processBitMap("image.png");
            mImageView.post(new Runnable() {
                public void run() {
                    mImageView.setImageBitmap(bitmap);
                }
            });
        }
    }).start();
}

The code can simply use the complete Dart:

onClick() async {
  Bitmap bitmap = await processBitMap("image.png");
  // you don't want to update non-existent widget
  if (!mounted) return;
  setState(() {
    imageView = bitmap;
  });
}

What happened here? async modifier marks will be arranged later execution method, the method becomes non-blocking, so your application without losing any frames, await modifier suspend execution method, wait processBitMap complete, then execution will resume.

Widget

There are a large variety of OEM software and skin running on top of Android, which is understandable, because each manufacturer looking to build their added value for their equipment, I can not calculate how many times I actually said "Funck S * ms * ng ", OEM customization of Android developers introduces a number of problems ..

Flutter, 120FPS order to achieve the goal, it has been decided to start on a blank canvas, use  Skia  2D graphics library for drawing each widget, rather than reusing OEM widget, and realize most Material Designa and general layout.

In this way, we can not guarantee that your application on multiple devices look the same, although not all have been optimized Flutter widget, you can also work properly on the device's smaller screen on a tablet.

In any case, this approach also opens new doors for innovative UI design, for example, the following code can cause the user to change the size of Activity:

class HeroScreen extends StatefulWidget {
  @override
  HeroState createState() => new HeroState();
}class HeroState extends State<HeroScreen> with SingleTickerProviderStateMixin {

  bool _scaling = false;

  Matrix4 _transformScale = new Matrix4.identity();
  double scalePos = 1.0;  set _scale(double value) =>
      _transformScale = new Matrix4.identity()..scale(value, value, 1.0);

  @override
  Widget build(BuildContext context) {    return new Scaffold(
        body: new GestureDetector(
            onScaleStart: (details) {
              setState(() {
                _scaling = true;
              });
            },
            onScaleUpdate: (details) {              var n = details.scale;
              setState(() {
                scalePos = n;
                _scale = n;
              });
            },
            onScaleEnd: (details) {
              setState(() {
                _scaling = false;
                _scale = scalePos < 1 ? 1.0 : scalePos;
              });
            },
            child: new Container(
                color: Colors.black26,
                child: new Transform(
                    transform: _transformScale,
                    child: new Center(
                        child: new Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[                          
new Text(_scaling ? "Scaling" : "Scale me up"),
                        ]))))));
  }
}

This allows us to get a very interesting widgets, so to write reusable widgets would be too easy, I can convert a less than friendly and clean code into reusable widgets:

class Scale extends StatefulWidget {  final Widget child;  final GestureScaleStartCallback onStart;  final GestureScaleEndCallback onEnd;  final GestureScaleUpdateCallback onUpdate;

  Scale({Key key, this.child, this.onStart, this.onUpdate, this.onEnd})
      : super();

  @override
  ScaleState createState() => new ScaleState();
}class ScaleState extends State<Scale> with SingleTickerProviderStateMixin {
  Matrix4 _transformScale = new Matrix4.identity();
  double scalePos = 1.0;  set _scale(double value) =>
      _transformScale = new Matrix4.identity()..scale(value, value, 1.0);

  @override
  Widget build(BuildContext context) {    return new GestureDetector(
        onScaleStart: widget.onStart,
        onScaleUpdate: (details) {
          widget.onUpdate(details);          var n = details.scale;
          setState(() {
            scalePos = n;
            _scale = n;
          });
        },
        onScaleEnd: (details) {
          widget.onEnd(details);
          setState(() {
            _scale = scalePos < 1 ? 1.0 : scalePos;
          });
        },
        child: new Container(
            color: Colors.black26,
            child: new Transform(
                transform: _transformScale, child: widget.child)));
  }
}

Code reconstructed as follows:

class HeroScreen extends StatefulWidget {
  @override
  HeroState createState() => new HeroState();
}class HeroState extends State<HeroScreen> with SingleTickerProviderStateMixin {
  bool _scaling = false;

  @override
  Widget build(BuildContext context) {    return new Scaffold(
        body: new Scale(
      onStart: (details) => setState(() => _scaling = true),
      onUpdate: (details) {},
      onEnd: (details) => setState(() => _scaling = false),
      child: new Container(
          color: Colors.black26,
          child: new Center(
              child: new Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[                new Text(_scaling ? "Scaling" : "Scale me up"),
              ]))),
    ));
  }
}

other

  • Instant called thermal run reloading takes less than a second

  • Flutter use the CPU to draw graphics rendering using the GPU, but some on 3D API is not available

  • Do not have to design the layout XML

  • Layout calculation only once the size tree

  • Even if there are grammatical errors will not crash your APP

  • Flutter widget can be embedded into the Android Activity

  • You can not embed Android library Flutter widget

  • At least 60 FPS, unless your machine is doing something else

  • React inspired by the design of the API, but did not like running React

  • It does not require any POJO  

Guess you like

Origin blog.csdn.net/zhangcanyan/article/details/91959657