Day 1: December 16, 2018 Weather: Cold

Zero foreword:

As an experienced Android amateur (self-described), it’s time to get into the Flutter pit,

Anyway, new technology is a bit of a learning curve, so this series will serve as a study note for me to start by writing about what it feels like to be in the hole today:

1. The construction of the environment has been stepped on by the predecessors, it is not very troublesome 2. Really surprised me ----- so the "fat man" image of the Flutter is deep in my heart (but the non-debug version can be within 10M, or acceptable) 3. The hot loading of the Flutter is very cool, for me who like to use the real machine, every time after modification --> determine to install --> open... The single quotation marks are lit up, which makes it possible to Shift less than in other languages, and the string interpolation is also very nice. My four main players (Canvas, Path, Paint, And Bezier) can perform their tasks again, but the Api is slightly different and slightly thinner. Programmers have three tools: Ctrl+ Z(bold change), debug(careful check), analogy (good analysis)Copy the code

First experience of Flutter

1. Download the SDK of Flutter

The Android SDK is configured in the environment variable ANDROID_HOME

Are there any problems that can be examined in CMD by using the Flutter doctor command

git clone -b beta https://github.com/flutter/flutter.git
Copy the code

2. Configure environment variables

PUB_HOSTED_URL=https://pub.flutter-io.cn
FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
Copy the code

Install Dart and Flutter plugins on AndroidStudio
Setting -->plugins--> search --> Install --> restartCopy the code

4. Create a new project

Open AS can be seen after a Flutter new projects, and then write the name the initializing gradle if has been fixed, android/gradle/wrapper/gradle – wrapper. Properties

The corresponding download gradle version at http://services.gradle.org/distributions/ himself, in the local


Second, the first time to see the initial project inner drama

Android: I am most familiar with android | -- - | app - SRC ios: temporarily don't bird it lib: . | - the main dart test: as the name suggests, the test package. Gitignore. Metadata. Packages pubspec. Lock pubspec. Yaml README. Md doesn't even have the package, temporarily ignoredCopy the code

1. 1. How to Make a livingandroid/app/src/main/AndroidManifest.xml
<application android:name="io.flutter.app.FlutterApplication" android:label="my_flutter" Android :icon="@mipmap/ ic_Launcher "> <activity android:name=".mainActivity" <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application>Copy the code

2. The visible program entry is mainActivity.java

Gives me a visual sense of libgdx

public class MainActivity extends FlutterActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GeneratedPluginRegistrant.registerWith(this); }}Copy the code

3.GeneratedPluginRegistrant.java
/** * Generated file. Do not edit. Automatically generated files, Do not modify * / public final class GeneratedPluginRegistrant {public static void registerWith (PluginRegistry registry) {if (alreadyRegisteredWith(registry)) {return; Private static Boolean alreadyRegisteredWith(PluginRegistry registry) {final String key = GeneratedPluginRegistrant.class.getCanonicalName(); If (registry. HasPlugin (key)) {return true; } registry.registrarFor(key); // Return false; }}Copy the code

4, who is dirty my white interface (display)
4.1.MainActivity is obviously not, how to check where?

Well, in: Main.dart

import 'package:flutter/material.dart'; void main() => runApp(MyApp()); -- -- -- -- -- -- -- -- -- -- -- -- acting / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- open object-oriented eye a see: ` void main () = > runApp (MyApp ()); It's not like Python, it's not like JavaScript, it's not like Java, but I seem to know what it's trying to do to me: I'm the entry function, I execute the runApp function, it passes MyApp(),so, I'm clean, it's MyApp()Copy the code

4.2. Cognition of MyApp
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); }} -- -- -- -- -- -- -- -- -- -- -- -- acting / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- to see the class there is a meet an old friend, We inherited the StatelessWidget class and overwrote its build method and returned a Widget object, and we can infer that The MaterialApp() is a Widget object where the parentheses feel a lot like a Python dictionary or JavaScript object, But it's kind of weird to wrap it in (). As usual, you have properties on the left and values on the right, so let's play around. So I'm going to change the theme and I'm going to pass in my home, which is MyHomePage, so I'm going to change the titleCopy the code


4.3. Cognition of MyHomePage
class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } -- -- -- -- -- -- -- -- -- -- -- -- acting / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- MyHomePage also StatefulWidget home, the first sentence feel rather strange, to mark the first super (key: This. Title should be the key to the StatefulWidget, so I want two parameters, CreateState () is a superclass method,_MyHomePageState () is a class, so _MyHomePageState() is an object,(ps: see State and think React)Copy the code

4.4. Cognition of _MyHomePageState
class _MyHomePageState extends State<MyHomePage> { int _counter = 0; Void _incrementCounter() {setState(() {_counter++; // Define the variable ++}); } -- -- -- -- -- -- -- -- -- -- -- -- acting / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- / / experience from JS and Python, from here you can see, seemingly with _, is don't want to be exposed internal members _incrementCounter () is clearly a cumulative method, The thing in setState() let's say _counter++ setState React which is exactly the same thing, mark, @Override Widget build(BuildContext Context) {return Scaffold(appBar: appBar (title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.display1, ), ], ), ), ------------ -------------- Abstract class State<T extends StatefulWidget> Extends Diagnosticable State has a generic StatefulWidget that overrides the build method. [Class Scaffold extends StatefulWidget] Scaffold is also a StatefulWidget Now the focus should be on StatefulWidget. There are a lot of widgets out there. Mark: Text(widget.title)----. Column, mainAxisAlignment, center, children, Text: You have pushed the button this many times: It's kind of fun to put it all together, and it's like, the column is centered for the kid, and the text is centered for the kid's main axis alignmentCopy the code
4.5. FloatingActionButton, the elements of the android
floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); } // onTip: Click on the response function tooltip-- Long press to display the text Child --Icon + imageCopy the code

Ok, so that’s what I felt the first time I looked at the Flutter code. Mark has three things,

Here’s a formal introduction to Dart with a question.


Dart grammar

1. The circumference of the circle
Const PI = 3.141592654; // double PI = 3.141592654; final x = 50; //final int x = 100; //final int x = 100; main() { // int radius = 10; var radius = 10; / / the radius = 10.0; //Error--A value of type 'double' can't be assigned to a variable of type 'int'. double c = getC(radius); Bool isBig = c > x; print(isBig ? "> ${x}" : r" > ${x}"*2); ${x} ${x} ${x} ${x} ${x} ${x} ${x} ${x} ${x} Double getC(int radius) {var c = 2 * PI * radius; return c; }Copy the code

1. It feels like a hero is born with const, and finally it feels like a level is reached. Choose a hero class (no transfer)

2. R will print the string as it is, ignoring the whitespaces. 3. The string *2 is printed twice. You can omit types, but you can’t assign other types if you initially assign them, so Dart is not a weakly typed language!! But say it is strong and not how rigorous, look at the picture below, powerless to ridicule… (PS: Cause: see dynamic type below)


2. The use of the List

Support for multiple types, more APIS than Java

You can think of Java’s ArrayList as a combination of arrays. Operations such as any,join, and so on are more like Lists in Python or JS

void baseUse() { var list = [1, "a", "b", "c", true]; // var list=const[1,"a","b","c",true]; // var list =new List(); list[0] = "10"; Var el = list[list.length-1]; var el = list[list.length-1]; // Get --true list.add("toly"); // add --[10, a, b, c, true, toly] list.insert(1, true); / / point to add - [10, true, a, b, c, true, toly] list. Remove (" 10 "); // Delete element --[true, a, b, c, true, toly] list.indexof (true); // First out index --1 list.lastIndexof (true); --4 list.removelast (); / / remove the tail - [true, a, b, c, true] print (list. The sublist (2)); --[b, c, true] print(list.sublist(2, 4)); --[b, c] print(list); print(list.join("!" )); //true! a! b! c! true }Copy the code

ForEach, any, every, map
void op() { var numList = [3, 2, 1, 4, 5]; numList.sort(); print(numList); [1, 2, 3, 4, 5] for (var value in numList) {print(value); / / 1, 2, 3, 4, 5} numList. ForEach (addOne); / / 2,3,4,5,6 numList. ForEach ((num) = > print (num + 1)); Var any = numlist. any((num) => num > 3); print(any); Var every = numlist. every((num) => num < 6); print(every); Var listX5 = numlist.map ((e) => e*=5); print(listX5); //(5, 10, 15, 20, 25) } int addOne(int num) { print(num + 1); }Copy the code

3.Map

I won’t say much about this, but it’s basically consistent with the mainstream language

Void baseUse () {/ / create a mapping table var dict = {" a ":" page1 ", "b" : "page30", "c" : "page70", "price" : 40}; // var dict = new Map(); print(dict); //{a: page1, b: page30, c: page70, price: 40} print(dict["price"]); //40 dict["a"] = "page2"; print(dict); //{a: page2, b: page30, c: page70, price: 40} print(dict.containsKey("price")); //true print(dict.containsValue("price")); //false print(dict.isEmpty); //false print(dict.isNotEmpty); //true print(dict.length); //4 dict.remove("c"); print(dict); //{a: page2, b: page30, price: 40} }Copy the code

void op() { var dict = {"a": "page1", "b": "page30", "c": "page70", "price": 40}; dict.keys.forEach(print); //a,b,c,price dict.values.forEach(print); //a,b,c,price dict.forEach((k, v) => (print("$k=$v"))); // This is the first time that... }Copy the code

4. This is a dynamic situation.

So dynamic, that makes the type dynamic

dynamic d = 20; d = "toly"; var list = new List<dynamic>(); list.add("1"); list.add(3); var list2 = new List<int>(); //list2.add("toly"); //ERROR:The argument type 'String' can't be assigned to the parameter type 'int'.Copy the code

5. Different things
//-------------------- strange ~/---------- int a=10; print(a/3); / / 3.3333333333333335 print (a ~ / 3); //3 //-------------------- strange?? =---------- int b = 9; b = 5; b ?? = a; //---- print(b); //5 //-------------------- strange?? ---------- int c = 10; int d = 8; var add10 = c = null ?? d + 10; Print (add10); // Print (add10); 18 / / / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- concise = > -- -- -- -- -- -- -- -- -- -- = > expr equivalent to {return expr. } / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- fun} {parameters -- -- -- -- -- -- -- -- -- -- the main () {fun (" toly "); Toly,24,null fun("toly", age: 24, sex: "male "); //toly,24, male} fun(String name, {int age=24, String sex}) {print("$name,$age,$sex"); } / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- fun [parameter] -- -- -- -- -- -- -- -- -- -- the main () {fun (" toly "); //toly,null,null fun2("toly", 24); } fun2(String name, [int age, String sex= "male "]) {print("$name,$age,$sex"); } / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- interesting anonymous methods -- -- -- -- -- -- -- -- -- -- var power (I) = {return I * I; }; print(power(6)); 36 / / / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the reason clearly, largely anonymous functions with respect to OK -- -- -- -- -- -- -- -- -- -- the var li = [1, 2, 3, 4, 5]. li.forEach((i) => print((i) { return i * i; }(i))); / / 1,4,9,16,25Copy the code

6. That sort of thing
6.1: Define a simple class

PerSon(this.name, this.age) simplifies the Java glob, but little else

class PerSon { String name; int age; PerSon(this.name, this.age); say(String name) { print("are you ok $name"); } } main(){ var toly = new PerSon("toly", 24); toly.say("ls"); //are you ok ls }Copy the code

6.2: inheritance

Pay attention to the grammatical form

class Student extends PerSon { String school; Student(String name, int age, this.school) : super(name, age); } the main () {new Student (" ls ", 23, "star dragon school"), say (" toly "); //are you ok toly }Copy the code

So much knowledge, should be enough to play.


Canvas walk

When you learn something new, it’s best to choose the point you’re most familiar with, which in my case is drawing

1. Where is the artboard

There’s a CustomPainter class that has canvas in it, so I’m inheriting it, so to avoid clutter, I created a new view package, View /star_view.dart

import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class StarView extends CustomPainter { @override void paint(Canvas canvas, Size size) { } @override bool shouldRepaint(CustomPainter oldDelegate) { return true; }}Copy the code

2. StarView usage

As we analyzed earlier, the view is rendered in the object returned by the createState method in MyHomePage and the build method

Just change the body of the text to CustomPaint and leave the FloatingActionButton there.

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: CustomPaint(
        painter: StarView(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
Copy the code

3. Obtain the screen size

All the units that the flutter uses are visually dp so I’m using the third line, and I need to pass in a context

Just pass it around in the constructor, and it happens that there’s a context in the build, so you can divide it by the first two

Window.physicalsize // Get the screen size px----1080.0, 2196.0 window.devicepixelratio // devicePixelRatio ----3 mediaquery.of (context).size // get dp unit :360.0, 732.0Copy the code
Body: CustomPaint(Painter: StarView(context),);Copy the code

4. The grid goes up:
4.1: StarView receives the context and initializes the brush
  Paint mHelpPaint;
  BuildContext context;

  StarView(this.context) {
    mHelpPaint = new Paint();
    mHelpPaint.style=PaintingStyle.stroke;
    mHelpPaint.color=Color(0xffBBC3C5);
    mHelpPaint.isAntiAlias=true;
  }
Copy the code

4.2: Draw the grid path

Functions previously used in Android have been modified for flutter

/** * draw gridPath ** @param step small square side length * @param winSize screen size */ Path gridPath(int step, Size winSize) { Path path = new Path(); for (int i = 0; i < winSize.height / step + 1; i++) { path.moveTo(0, step * i.toDouble()); path.lineTo(winSize.width, step * i.toDouble()); } for (int i = 0; i < winSize.width / step + 1; i++) { path.moveTo(step * i.toDouble(), 0); path.lineTo(step * i.toDouble(), winSize.height); } return path; }Copy the code

4.3: Draw the grid
  @override
  void paint(Canvas canvas, Size size) {
    var winSize = MediaQuery.of(context).size;
    canvas.drawPath(gridPath(20, winSize), mHelpPaint);
Copy the code


4.4 coordinate system drawing

DrawCoo (Canvas Canvas, Size COO, Size winSize) {// Initialize the grid Paint Paint = new Paint(); paint.strokeWidth = 2; paint.style = PaintingStyle.stroke; DrawPath (cooPath(COO, winSize), paint); // Canvas. DrawLine (new Offset(winsize.width, coo.height), new Offset(winsize.wid-10, COO.height-6), paint); canvas.drawLine(new Offset(winSize.width, coo.height), new Offset(winSize.width - 10, coo.height + 6), paint); // Canvas. DrawLine (new Offset(coo.width, winsize.height-90), new Offset(COO.wid-6, winsize.height-10-90), paint); canvas.drawLine(new Offset(coo.width, winSize.height-90), new Offset(coo.width + 6, winSize.height - 10-90), paint); }Copy the code

Coordinate path

@param winSize @param winSize @return @param winSize */ Path cooPath(Size COO, Size winSize) { Path path = new Path(); Var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var; path.lineTo(winSize.width, coo.height); Var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var var path.lineTo(coo.width - winSize.width, coo.height); //y negative half axis path.moveto (coo.width, coo.height); path.lineTo(coo.width, coo.height - winSize.height); //y negative half axis path.moveto (coo.width, coo.height); path.lineTo(coo.width, winSize.height); return path; }Copy the code

5. Summary

Feel the Canvas in Flutter is weak… I don’t know if I didn’t find it or what

Canvas can not draw text, it is not scientific, mark. That’s the only way the coordinate system works and the Color is a little awkward, why do we have to Offset, we don’t even have a reload


6. Draw n-angle stars

All right, I’m gonna embarrass myself with the stars again

I have translated the Java code of n-star into dart dialect

/ * * @ * * * n Angle star Path param num several star * @ param R * @ param circumscribed circle radius R inscribed circle radius Angle star Path * * @ return n/Path nStarPath (int num, double R, double r) { Path path = new Path(); double perDeg = 360 / num; Double degA = perDeg / 2; double degA = perDeg / 2; double degB = 360 / (num - 1) / 2 - degA / 2 + degA; path.moveTo(cos(_rad(degA)) * R, (-sin(_rad(degA)) * R)); for (int i = 0; i < num; i++) { path.lineTo( cos(_rad(degA + perDeg * i)) * R, -sin(_rad(degA + perDeg * i)) * R); path.lineTo( cos(_rad(degB + perDeg * i)) * r, -sin(_rad(degB + perDeg * i)) * r); } path.close(); return path; } double _rad(double deg) { return deg * pi / 180; }Copy the code
canvas.translate(160, 320); DrawPath (nStarPath(5,80,40), mPaint);Copy the code


7. N-angle stars and regular polygons
7.1: Method encapsulation
/** * Draw the path of the n-angle star: * * @param R = @param R = @param R = @param R = @param R */ regularStarPath(int num, double R) {double degA, degB; If (num % 2 == 1) {// degA = 360 / num / 2/2; degB = 180 - degA - 360 / num / 2; } else { degA = 360 / num / 2; degB = 180 - degA - 360 / num / 2; } double r = R * sin(_rad(degA)) / sin(_rad(degB)); return nStarPath(num, R, r); } @param R regularPolygonPath(int num) ** @param R regularPolygonPath(int num) ** @param R regularPolygonPath(int num) ** @param R regularPolygonPath(int num) ** @param R regularPolygonPath(int num), double R) { double r = R * cos(_rad(360 / num / 2)); / /!!!!! Return nStarPath(num, R, R); }Copy the code

7.2. Batch drawing:
canvas.translate(0, 320); canvas.save(); For (int I = 5; i < 10; i++) { canvas.translate(64, 0); canvas.drawPath(nStarPath(i, 30, 15), mPaint); } canvas.restore(); canvas.translate(0, 70); canvas.save(); For (int I = 5; i < 10; i++) { canvas.translate(64, 0); canvas.drawPath(regularStarPath(i, 30), mPaint); } canvas.restore(); canvas.translate(0, 70); canvas.save(); For (int I = 5; i < 10; i++) { canvas.translate(64, 0); canvas.drawPath(regularPolygonPath(i, 30), mPaint); } canvas.restore();Copy the code


8. State control, click random color

Click on the first button of fab to change the number, here to change the color to try:

//-----------main.dart------------------- Color _color = Colors.black; void _changeColor() { setState(() { _color=randomRGB(); }); } body: CustomPaint( painter: StarView(context,_color), ), floatingActionButton: FloatingActionButton( onPressed: _changeColor, tooltip: 'Increment', child: Icon (the Icons. Add),), / / -- -- -- -- -- -- -- -- -- -- - Random Color -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- Color randomRGB () {Random Random = new Random (); int r = 30 + random.nextInt(200); int g = 30 + random.nextInt(200); int b = 30 + random.nextInt(200); return Color.fromARGB(255, r, g, b); } //-----------star_view.dart------------------- StarView(this.context,Color color) { print(color); mPaint = new Paint(); mPaint.color = color; }Copy the code


Let’s bring together today’s Mark

After an analysis of the initial project and a brief introduction to the Dart dialect, plus Canvas drawing

Basically familiarize yourself with the grammar of Dart and the routine of the Flutter (much like React), so that’s it for the first day

1. SetState and React are exactly the same, mark will probably refresh the interface ---- after testing, yes, calling setState will redraw the interface, just like ReactCopy the code
2.MyHomePage is also a StatefulWidget. The first sentence feels weird. Class MyHomePage extends StatefulWidget {MyHomePage({Key Key, this.title}) : super(Key: Key); ---- With the syntax of inheritance and the optional argument to {}, it's not hard to understand that key is taken from dadCopy the code
3. Now the focus should be on StatefulWidget, there are many places,mark - keep mark 4. Canvas can not draw text, it is not scientific,mark - keep markCopy the code

Postscript: Jie wen standard

1. Growth record and Errata of this paper
Program source code The date of note
V0.1 – making 2018-12-16 Day 1 — Initial analysis +Dart Dialect +Canvas Sketch
2. More about me
Pen name QQ WeChat hobby
Zhang Feng Jie te Li 1981462002 zdl1994328 language
My lot My Jane books I’m the nuggets Personal website
3. The statement

1—- This article is originally written by Zhang Fengjie, please note if reproduced

2—- welcome the majority of programming enthusiasts to communicate with each other 3—- personal ability is limited, if there is something wrong welcome to criticize and testify, must be humble to correct 4—- see here, I thank you here for your love and support