The original link

More tutorials


If you have mobile development experience, whether you are an iOS or Android developer, you can use your existing knowledge to quickly understand Flutter development. This article will illustrate the differences between two-ended development and Flutter.

Flutter withWidgetRepresents (UIView on iOS) and (View on Android)

Widgets are used in Flutter to represent the view concept in two-end development. Just like a view in both ends, it can also contain other widgets.

The difference is:

  • When the widgets and their states are changed in a Flutter, the Flutter builds a new tree of widgets. Unlike UIView, Flutter widgets are very lightweight because of their immutability.
  • Uiviews in iOS are not recreated when changed, and are not redrawn until setNeedsDisplay() is used.
  • Views on Android are not recreated when they are changed until they are redrawn when invalidate is called.

In the Flutter throughStatefulWidgetUpdate widget status

  • IOS and Android can directly modify UIView or View property value, to achieve the purpose of changing the state
  • Flutter modifies the widget state by using the StatefulWidget

So what is a StatefulWidget?

There are two types of widgets in Fullter, the stateful StatefulWidget and the stateless StatelessWidget.

  • StatefulWidget has a State object to store its State data, and you can modify the UI performance of the StatefulWidget by changing the value of the State object.
  • The StatelessWidget is just as it sounds, a widget with no attached state. For example, a logo image that does not change at runtime can be represented in the StatelessWidget.

Here’s an example of turning an immutable state widget into a stateful widget:

Text(
  'I like Flutter! ',
  style: TextStyle(fontWeight: FontWeight.bold),
);
Copy the code

The Text widget carries no other state. It renders from data passed to its constructor. When you want to modify the Text value with a user click, you can wrap the Text Widget with a StatefulWidget and update it when the user clicks the button.

class SampleApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, ), home: SampleAppPage(), ); }}class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

  @override
  _SampleAppPageState createState() => _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  // Default placeholder text
  String textToShow = "I Like Flutter";
  void _updateText() {
    setState(() {
      // update the text
      textToShow = "Flutter is Awesome!";
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: Center(child: Text(textToShow)),
      floatingActionButton: FloatingActionButton(
        onPressed: _updateText,
        tooltip: 'Update Text', child: Icon(Icons.update), ), ); }}Copy the code

The interface of Flutter is drawn through the Widget tree

  • In iOS, interfaces are drawn by code or storyboard or XIB
  • Android writes layouts in XML
  • The interface of Flutter is drawn through the Widget tree

An example: Display a simple Widget on the screen and add some padding.

@override
Widget build(BuildContext context) {
  return new Scaffold(
    appBar: new AppBar(
      title: new Text("Sample App"),
    ),
    body: new Center(
      child: new MaterialButton(
        onPressed: () {},
        child: new Text('Hello'),
        padding: new EdgeInsets.only(left: 10.0, right: 10.0),),),); }Copy the code

How can I dynamically add or remove FlutterWidget

  • In Android, you can dynamically add or remove views by calling addChild or removeChild from a parent control.
  • In iOS, you dynamically add or remove child views by calling addSubview() in the parent view or removeFromSuperview() in the child View.
  • In Flutter, there is no addChild because the widget is immutable. You can determine whether to display a particular control by changing a bool value and then redrawing it.

For example: click on a button to display a widget that doesn’t work:

import 'package:flutter/material.dart';

void main() {
  runApp(new SampleApp());
}

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Sample App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: newSampleAppPage(), ); }}class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

  @override
  _SampleAppPageState createState() => new _SampleAppPageState();
}

class _SampleAppPageState extends State<SampleAppPage> {
  // Default value for toggle
  bool toggle = true;
  void_toggle() { setState(() { toggle = ! toggle; }); } _getToggleChild() {if (toggle) {
      return new Text('1111111');
    } else {
      return new MaterialButton(onPressed: () {}, child: new Text('2222222')); }}@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Sample App"),
      ),
      body: new Center(
        child: _getToggleChild(),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _toggle,
        tooltip: 'Update Text',
        child: newIcon(Icons.update), ), ); }}Copy the code

How does Flutter use animation

  • In iOS, you animate a view by calling the animate(withDuration: Animations 🙂 method.
  • In Android, you can create an animation from XML or call.animate() on a view.
  • Instead of creating an animation widget, use animation libraries to wrap widgets in Flutter. In Flutter, AnimationController is used to control animation pause, find, stop, reverse animation, etc. Use an extension of the Animation class such as CurvedAnimation to implement a interpolated curve.

Example: Click the button in the lower right corner to fade out the icon:

Code:

import 'package:flutter/material.dart';

void main() {
  runApp(new FadeAppTest());
}

class FadeAppTest extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Fade Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyFadeTest(title: 'Fade Demo')); }}class MyFadeTest extends StatefulWidget {
  MyFadeTest({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyFadeTest createState() => new _MyFadeTest();
}

class _MyFadeTest extends State<MyFadeTest> with TickerProviderStateMixin {
  AnimationController controller;
  CurvedAnimation curve;

  @override
  void initState() {
    controller = new AnimationController(
        duration: const Duration(milliseconds: 2000), vsync: this);
    curve = new CurvedAnimation(parent: controller, curve: Curves.easeIn);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
          child: new Container(
              child: new FadeTransition(
                  opacity: curve,
                  child: new FlutterLogo(
                    size: 100.0,
                  )))),
      floatingActionButton: new FloatingActionButton(
        tooltip: 'Fade',
        child: newIcon(Icons.brush), onPressed: () { controller.forward(); },),); }}Copy the code

How does Flutter map?

  • On iOS, you use CoreGraphics to draw lines and shapes on the screen.
  • In Android, you can use Canvas to draw custom shapes on the screen.
  • In Flutter, the CustomPaint and CustomPainter classes help you draw.

For example:

code

import 'package:flutter/material.dart';

class SignaturePainter extends CustomPainter {
  SignaturePainter(this.points);

  final List<Offset> points;

  void paint(Canvas canvas, Size size) {
    Paint paint = newPaint() .. color = Colors.black .. strokeCap = StrokeCap.round .. strokeWidth =5.0;
    for (int i = 0; i < points.length - 1; i++) {
      if(points[i] ! =null && points[i + 1] != null)
        canvas.drawLine(points[i], points[i + 1], paint); }}boolshouldRepaint(SignaturePainter other) => other.points ! = points; }class Signature extends StatefulWidget {
  SignatureState createState() => new SignatureState();
}

class SignatureState extends State<Signature> {
  List<Offset> _points = <Offset>[];

  Widget build(BuildContext context) {
    return newStack( children: [ GestureDetector( onPanUpdate: (DragUpdateDetails details) { RenderBox referenceBox = context.findRenderObject();  Offset localPosition = referenceBox.globalToLocal(details.globalPosition); setState(() { _points =new List.from(_points).. add(localPosition); }); }, onPanEnd: (DragEndDetails details) => _points.add(null),
        ),
        CustomPaint(painter: newSignaturePainter(_points)) ], ); }}class DemoApp extends StatelessWidget {
  Widget build(BuildContext context) => new Scaffold(body: new Signature());
}

void main() => runApp(new MaterialApp(home: new DemoApp()));
Copy the code

How does Flutter create custom widgets?

  • Both iOS and Android implement this by inheriting views.
  • Flutter is the implementation of complex widgets by combining existing widgets.

For example, if you were to build a CustomButton and pass its label in the constructor, right? Instead of extending RaisedButton, combine RaisedButton and Label.

class CustomButton extends StatelessWidget {
  final String label;

  CustomButton(this.label);

  @override
  Widget build(BuildContext context) {
    returnRaisedButton(onPressed: () {}, child: Text(label)); }}Copy the code

Then use your CustomButton just like you would use any other Flutter widget:

@override
Widget build(BuildContext context) {
  return Center(
    child: CustomButton("Hello")); }Copy the code

Please stay tuned for the rest of this article because it is too long and will be divided into several parts.

The original link

More tutorials