[рдбреЙрдХ рджреНрд╡рд╛рд░рд╛] рд╕реНрдкрдВрджрдиред рднрд╛рдЧ 5. рдЬрд╝рд╛рдорд░реАрди рдХреЗ рд▓рд┐рдП

рдпрд╣ рдлрд╝реНрд▓рдЯрд░ рдкреНрд░рд▓реЗрдЦрди рдХреА рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд╛ рдЕрдВрддрд┐рдо рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдЬреЛ Xamarin.Forms рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдЕрдм рдХреБрдЫ рдирдпрд╛ рд╕реАрдЦрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ! рдХрдЯреМрддреА рдХреЗ рддрд╣рдд, рдЖрдк рдЕрдкрдиреЗ рдЖрдк рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдЬрд╛рдирдХрд╛рд░реА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдПрдХ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВ рдЬрд╛рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдХрд┐рддрдирд╛ рд╕рдордп рд▓рдЧреЗрдЧрд╛ред



рдпрджрд┐ рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ рдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдордВрдЪ рдХреЗ рд▓рд┐рдП рджреЗрд╢реА рд╡рд┐рдХрд╛рд╕ рдХрд╛ рдЕрдиреБрднрд╡ рд╣реИ, рддреЛ рдореИрдВ рдЕрдиреНрдп рднрд╛рдЧреЛрдВ рдореЗрдВ рджреЗрдЦрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ:

рд╕реНрдкрдВрджрдиред рднрд╛рдЧ 1. Android рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП
рд╕реНрдкрдВрджрдиред рднрд╛рдЧ 2. iOS рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП
рд╕реНрдкрдВрджрдиред рднрд╛рдЧ 3. рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдореВрд▓
рд╕реНрдкрдВрджрди рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП ред рднрд╛рдЧ 4. рд╕реНрдкрдВрджрди рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП
ред рднрд╛рдЧ 5. рдЬрд╝рд╛рдорд░реАрди рдХреЗ рд▓рд┐рдП

рд╕рд╛рдордЧреНрд░реА:


  1. рдкрд░рд┐рдпреЛрдЬрдирд╛

  2. Views



  3. Async UI





  4. Layouts



  5. ListView

  6. рдЯреЗрдХреНрд╕реНрдЯ

  7. рд╕реНрдкрдВрджрди рдкреНрд▓рдЧрдЗрдиреНрд╕

  8. рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдб

  9. рдбрд┐рдмрдЧрд┐рдВрдЧ

  10. рд╕реНрдерд╛рдиреАрдп рднрдВрдбрд╛рд░



рдкрд░рд┐рдпреЛрдЬрдирд╛


рд╕рд╡рд╛рд▓:


рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдХрд╣рд╛рдВ рд╣реИ?

рдЙрддреНрддрд░:


рдХрд╛рд░реНрдп main()ред

рдЕрдВрддрд░:


Xamarin.Forms рдореЗрдВ рдпрд╣ рд╣реИ LoadApplication(new App());ред

рдЙрджрд╛рд╣рд░рдг:


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

рд╕рд╡рд╛рд▓:


рдкреЗрдЬ рдпрд╛ рдПрд▓рд┐рдореЗрдВрдЯ рдХреИрд╕реЗ рдмрдирд╛рдПрдВ ?

рдЙрддреНрддрд░:


Flutter рдореЗрдВ рдкреЗрдЬ рдФрд░ рдПрд▓рд┐рдореЗрдВрдЯ рдХреА рдХреЛрдИ рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд╣реАрдВ рд╣реИ ред рд╕рднреА рдШрдЯрдХ рд╡рд┐рдЬреЗрдЯ рд╣реИрдВред рд╕реНрдкрдВрджрди рдореЗрдВ 2 рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдЬреЗрдЯ рд╣реИрдВ: рд╕реНрдЯреЗрдЯрд▓реЗрд╕рд╡рд┐рдЬреЗрдЯ рдФрд░ рд╕реНрдЯреЗрдЯрдлреБрд▓рд╡реЗрдЯ ред рд╡реЗ рдЙрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдПрдХрдорд╛рддреНрд░ рдЕрдВрддрд░ рдкреНрд░рддрд┐рдкрд╛рджрди рд░рд╛рдЬреНрдп рдореЗрдВ рд╣реИред

рдЕрдВрддрд░:


рд╕реНрдЯреЗрдЯрд▓реЗрд╕рд╡рд┐рдЬреЗрдЯ рдореЗрдВ рдПрдХ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╕реНрдерд┐рддрд┐ рд╣реИред рдкрд╛рда, рд▓реЛрдЧреЛ рдЗрддреНрдпрд╛рджрд┐ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИред рдЙрдиред рдпрджрд┐ рд╕реНрдХреНрд░реАрди рдкрд░ рдореМрдЬреВрдж рддрддреНрд╡ рдкреВрд░реЗ рдбрд┐рд╕реНрдкреНрд▓реЗ рдЯрд╛рдЗрдо рдХреЗ рджреМрд░рд╛рди рдирд╣реАрдВ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП, рддреЛ рдпрд╣ рдЖрдкрдХреЛ рд╕реВрдЯ рдХрд░рддрд╛ рд╣реИред рдЗрд╕реЗ рд╕реНрдЯреЗрдЯрдлреБрд▓ рд╡рд┐рдЬреЗрдЯ рдХреЗ рд▓рд┐рдП рдХрдВрдЯреЗрдирд░ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

StatefulWidget рдореЗрдВ рд░рд╛рдЬреНрдп рд╡рд░реНрдЧ рд╣реИ , рдЬреЛ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдХреБрдЫ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░рддреЗ рд╕рдордп рд╕реНрдХреНрд░реАрди рдкрд░ рдПрдХ рддрддреНрд╡ рдХреЛ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рд╕рд░реНрд╡рд░ рд╕реЗ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЖрдИ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдПрдХ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛, рдЖрджрд┐) - рдпрд╣ рдЖрдкрдХрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реИред

рдЙрджрд╛рд╣рд░рдг:


StatelessWidget:
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

StatefulWidget:
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        // Take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set the appbar title.
        title: new Text(widget.title),
      ),
      body: new Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}

рджреГрд╢реНрдп


рд╕рд╡рд╛рд▓:


рд╡рд┐рдЬреЗрдЯреНрд╕ рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреИрд╕реЗ рдХрд░реЗрдВ? рдХрд┐рд╕реА XAMLрдлрд╛рдЗрд▓ рдХреЗ рдмрд░рд╛рдмрд░ рдХреНрдпрд╛ рд╣реИ ?

рдЙрддреНрддрд░:


рд╕реНрдкрдВрджрди рдореЗрдВ, рд▓реЗрдЖрдЙрдЯ рд╕реАрдзреЗ рд╡рд┐рдЬреЗрдЯ рдЯреНрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреЛрдб рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЕрдВрддрд░:


Xamarin.Forms рдореЗрдВ, рд╕рдмрд╕реЗ рдЕрдХреНрд╕рд░ рд▓реЗрдЖрдЙрдЯ рдПрдХ XAML.file рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред рд╕реНрдкрдВрджрди рдХреЗ рдХреЛрдИ рд╕рдордХрдХреНрд╖ рдирд╣реАрдВ рд╣реИред

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:


рд╡рд┐рдЧреЗрдЯреНрд╕ рдХреА рд╕реВрдЪреА рдпрд╣рд╛рдВ рджреЗрдЦреА рдЬрд╛ рд╕рдХрддреА рд╣реИ ред

рдЙрджрд╛рд╣рд░рдг:


@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),
      ),
    ),
  );
}

рд╕рд╡рд╛рд▓:


рдХреЛрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд┐рдЬреЗрдЯ рдХреИрд╕реЗ рдЬреЛрдбрд╝реЗрдВ рдпрд╛ рдирд┐рдХрд╛рд▓реЗрдВ?

рдЙрддреНрддрд░:


рдкреИрд░реЗрдВрдЯ рд╡рд┐рдЬреЗрдЯ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдХреЗ рдФрд░ рдлрд┐рд░ рд╡рд┐рдЬреЗрдЯ рдЯреНрд░реА рдХрд╛ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдгред

рдЕрдВрддрд░:


Xamarin.Forms рдореЗрдВ, рдпрд╣ ContentрддрддреНрд╡ рдпрд╛ рд╡рд┐рдзрд┐рдпреЛрдВ Add()рдФрд░ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ Remove()ред

рдЙрджрд╛рд╣рд░рдг:


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

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('Toggle One');
    } else {
      return new CupertinoButton(
        onPressed: () {},
        child: new Text('Toggle Two'),
      );
    }
  }

  @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: new Icon(Icons.update),
      ),
    );
  }
}

рд╕рд╡рд╛рд▓:


рдХреИрд╕реЗ рдПрдХ рд╡рд┐рдЬреЗрдЯ рдЪреЗрддрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП?

рдЙрддреНрддрд░:


рдПрдиреАрдореЗрд╢рди рдФрд░ рдПрдирд┐рдореЗрд╢рдирдХрдВрдЯреНрд░реЛрд▓рд░ рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдЕрдВрддрд░:


Xamarin.Forms ViewExtensions рдФрд░ рдЬреИрд╕реЗ FadeToрдпрд╛ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ TranslateToред

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:


рдПрдиреАрдореЗрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдпрд╣рд╛рдБ рдкрдврд╝реЗрдВ ред

рдЙрджрд╛рд╣рд░рдг:


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: new Icon(Icons.brush),
        onPressed: () {
          controller.forward();
        },
      ),
    );
  }
}

рд╕рд╡рд╛рд▓:


рд╕реНрдХреНрд░реАрди рдкрд░ рдХреИрд╕реЗ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


CustomPaint рдФрд░ CustomPainter рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдЕрдВрддрд░:


Xamarin.Forms рдПрдХ рддреАрд╕рд░реА рдкрд╛рд░реНрдЯреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ SkiaSharp ред рд╕реНрдкрдВрджрди рдореЗрдВ, рд╕реНрдХрд┐рдпрд╛ рдХреИрдирд╡рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реАрдзреЗ рдмреЙрдХреНрд╕ рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг:


import 'package:flutter/material.dart';

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

class DemoApp extends StatelessWidget {
  Widget build(BuildContext context) => new Scaffold(body: new Signature());
}

class Signature extends StatefulWidget {
  SignatureState createState() => new SignatureState();
}

class SignatureState extends State<Signature> {
  List<Offset> _points = <Offset>[];
  Widget build(BuildContext context) {
    return new GestureDetector(
      onPanUpdate: (DragUpdateDetails details) {
        setState(() {
          RenderBox referenceBox = context.findRenderObject();
          Offset localPosition =
          referenceBox.globalToLocal(details.globalPosition);
          _points = new List.from(_points)..add(localPosition);
        });
      },
      onPanEnd: (DragEndDetails details) => _points.add(null),
      child: new CustomPaint(painter: new SignaturePainter(_points), size: Size.infinite),
    );
  }
}

class SignaturePainter extends CustomPainter {
  SignaturePainter(this.points);
  final List<Offset> points;
  void paint(Canvas canvas, Size size) {
    var paint = new Paint()
      ..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);
    }
  }
  bool shouldRepaint(SignaturePainter other) => other.points != points;
}

рд╕рд╡рд╛рд▓:


рдкрд╛рд░рджрд░реНрд╢рд┐рддрд╛ рдХреИрд╕реЗ рдмрджрд▓реЗрдВ?

рдЙрддреНрддрд░:


Opacity рд╡рд┐рдЬреЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдЕрдВрддрд░:


Xamarin.Forms рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рдХреА VisualElement ред рд╕реНрдкрдВрджрди рдореЗрдВ, рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рдореЗрдВ рд╡рд╛рдВрдЫрд┐рдд рд╡рд┐рдЬреЗрдЯ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред

рд╕рд╡рд╛рд▓:


рдХрд╕реНрдЯрдо рд╡рд┐рдЬреЗрдЯ рдХреИрд╕реЗ рдмрдирд╛рдПрдВ?

рдЙрддреНрддрд░:


рдЙрдиреНрд╣реЗрдВ рдПрдХ (рд╡рд┐рд░рд╛рд╕рдд рдХреЗ рдмрдЬрд╛рдп) рдХреЗ рдЕрдВрджрд░ рд▓рд┐рдЦреЗрдВред

рдЕрдВрддрд░:


Xamarin.Forms рдореЗрдВ, рдЖрдк VisualElement рд╕реЗ рд╡рд╛рд░рд┐рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдореЗрдВ рд░реБрдЪрддрд╛ рд╣реИ рдФрд░ рдЕрдкрдирд╛ рддрд░реНрдХ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рд╕реНрдкрдВрджрди рдореЗрдВ, рдПрдХ рд╡рд┐рдЬреЗрдЯ рд╣рдореЗрд╢рд╛ рд╕реНрдЯреЗрдЯрд▓реЗрд╕рд╡рд┐рдЬреЗрдЯ рдФрд░ рд╕реНрдЯреЗрдЯрдлреБрд▓рд╡рд┐рдЬреЗрдЯ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ ред рдЙрдиред рдЖрдкрдХреЛ рдПрдХ рдирдпрд╛ рд╡рд┐рдЬреЗрдЯ рдмрдирд╛рдиреЗ рдФрд░ рдкреИрд░рд╛рдореАрдЯрд░ рдпрд╛ рдлрд╝реАрд▓реНрдб рдХреЗ рд░реВрдк рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╡рд┐рдЬреЗрдЯ рдХреЗ рд╕реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг:


class CustomButton extends StatelessWidget {
  final String label;

  CustomButton(this.label);

  @override
  Widget build(BuildContext context) {
    return new RaisedButton(onPressed: () {}, child: new Text(label));
  }
}

рдкрде рдкреНрд░рджрд░реНрд╢рди


рд╕рд╡рд╛рд▓:


рд╕реНрдХреНрд░реАрди рдХреЗ рдмреАрдЪ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХреИрд╕реЗ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рд╕реНрдХреНрд░реАрди рдХреЗ рдмреАрдЪ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдиреЗрд╡рд┐рдЧреЗрдЯрд░ рдФрд░ рд░реВрдЯ рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред

рдЕрдВрддрд░:


Xamarin.Forms рдиреЗрд╡рд┐рдЧреЗрд╢рдирдкреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ ред

рдлрд╝реНрд▓рдЯрд░ рдореЗрдВ рджреЛ рдиреЗрд╡рд┐рдЧреЗрд╢рди рддрд░реАрдХреЗ рд╣реИрдВ рдЬреЛ рдХрд┐ рдиреЗрд╡рд┐рдЧреЗрд╢рдирдкреЗрдЬ рдХреЗ рд╕рдорд╛рди рд╣реИрдВ :

  1. рдорд╛рд░реНрдЧ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╛рдореЛрдВ рдХреЛ рдореИрдк рдХрд░реЗрдВ ;
  2. рд╕реАрдзреЗ рд░реВрдЯ рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░реЗрдВ ред

рдиреЗрд╡рд┐рдЧреЗрдЯрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдзрдХреНрдХрд╛ () рдпрд╛ () рдкреЙрдк рдорд╛рд░реНрдЧ рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред

рдЙрджрд╛рд╣рд░рдг:


void main() {
  runApp(CupertinoApp(
    home: MyAppHome(), // becomes the route named '/'
    routes: <String, WidgetBuilder> {
      '/a': (BuildContext context) => MyPage(title: 'page A'),
      '/b': (BuildContext context) => MyPage(title: 'page B'),
      '/c': (BuildContext context) => MyPage(title: 'page C'),
    },
  ));
}

Navigator.of(context).pushNamed('/b');

рд╕рд╡рд╛рд▓:


рддреГрддреАрдп-рдкрдХреНрд╖ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХреИрд╕реЗ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


MethodChannel рдпрд╛ url_launcher рдкреНрд▓рдЧрдЗрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдореВрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдПрд╕рд┐рдВрдХреНрд╕ рдпреВрдЖрдИ


рд╕рд╡рд╛рд▓:


Device.BeginInvokeOnMainThread () рдХреЗ рд╕рдорддреБрд▓реНрдп рдХреНрдпрд╛ рд╣реИ ? рдХреЛрдб рдХреЛ рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рдбрд╛рд░реНрдЯ рдЖрдЗрд╕реЛрд▓реЗрдЯреНрд╕ рдкрд░ рдЪрд▓рдиреЗ рд╡рд╛рд▓реЗ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рдирд┐рд╖реНрдкрд╛рджрди рдореЙрдбрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ ред рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП, рдПрд╕рд┐рдВрдХреНрд╕ / рд╡реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЬрд┐рд╕реЗ рдЖрдк C # рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг:


рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдФрд░ UI рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдХрд░рдирд╛:
loadData() async {
  String dataURL = "https://jsonplaceholder.typicode.com/posts";
  http.Response response = await http.get(dataURL);
  setState(() {
    widgets = json.decode(response.body);
  });
}

рдЬрдм рдЕрдиреБрд░реЛрдз рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреА рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдирдП рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рд╡рд┐рдЬреЗрдЯ рдЯреНрд░реА рдХреЛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯрд╕реНрдЯреЗрдЯ () рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ ред рд╕реВрдЪреА

рдореЗрдВ рдбреЗрдЯрд╛ рд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг :
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

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

class SampleApp extends StatelessWidget {
  @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> {
  List widgets = [];

  @override
  void initState() {
    super.initState();

    loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: ListView.builder(
          itemCount: widgets.length,
          itemBuilder: (BuildContext context, int position) {
            return getRow(position);
          }));
  }

  Widget getRow(int i) {
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Text("Row ${widgets[i]["title"]}")
    );
  }

  loadData() async {
    String dataURL = "https://jsonplaceholder.typicode.com/posts";
    http.Response response = await http.get(dataURL);
    setState(() {
      widgets = json.decode(response.body);
    });
  }
}

рд╕рд╡рд╛рд▓:


рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рдХреИрд╕реЗ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


Http рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдЙрджрд╛рд╣рд░рдг:


рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ pubspec.yaml:
dependencies:
  ...
  http: ^0.11.3+16

рдкреВрдЫрддрд╛рдЫ:
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
[...]
  loadData() async {
    String dataURL = "https://jsonplaceholder.typicode.com/posts";
    http.Response response = await http.get(dataURL);
    setState(() {
      widgets = json.decode(response.body);
    });
  }
}

рд╕рд╡рд╛рд▓:


рд▓рдВрдмреЗ рд╕рдВрдЪрд╛рд▓рди рдХреА рдкреНрд░рдЧрддрд┐ рдХреИрд╕реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


ProgressIndicator рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдЕрдВрддрд░:


Xamarin.Forms рдореЗрдВ, рдпрд╣ рд╕реАрдзреЗ рдкреНрд░рдЧрддрд┐ рд╕реВрдЪрдХ рдХреЛ рдЕрдВрджрд░ рд░рдЦрдХрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ XAMLред

рдЙрджрд╛рд╣рд░рдг:


import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

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: new SampleAppPage(),
    );
  }
}

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

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

class _SampleAppPageState extends State<SampleAppPage> {
  List widgets = [];

  @override
  void initState() {
    super.initState();
    loadData();
  }

  showLoadingDialog() {
    return widgets.length == 0;
  }

  getBody() {
    if (showLoadingDialog()) {
      return getProgressDialog();
    } else {
      return getListView();
    }
  }

  getProgressDialog() {
    return new Center(child: new CircularProgressIndicator());
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Sample App"),
        ),
        body: getBody());
  }

  ListView getListView() => new ListView.builder(
      itemCount: widgets.length,
      itemBuilder: (BuildContext context, int position) {
        return getRow(position);
      });

  Widget getRow(int i) {
    return new Padding(padding: new EdgeInsets.all(10.0), child: new Text("Row ${widgets[i]["title"]}"));
  }

  loadData() async {
    String dataURL = "https://jsonplaceholder.typicode.com/posts";
    http.Response response = await http.get(dataURL);
    setState(() {
      widgets = json.decode(response.body);
    });
  }
}

рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕рдВрд░рдЪрдирд╛ рдФрд░ рд╕рдВрд╕рд╛рдзрди


рд╕рд╡рд╛рд▓:


рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рд╕реНрддрд╛рд╡реЛрдВ рдХреЗ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдХрд╣рд╛рдБ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рдореЗрдВ assetsред

рдЕрдВрддрд░:


Xamarin.Forms рдореЗрдВ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХреАрдХреГрдд рднрдВрдбрд╛рд░рдг рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдЙрдиреНрд╣реЗрдВ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЕрд▓рдЧ рд╕реЗ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдПрдХ рд╕реНрдкрдВрджрди рд╣реИ assetsред рдлрд╝реЛрд▓реНрдбрд░ assetsрдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХрд╣реАрдВ рднреА рд╕реНрдерд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрде рд▓рд┐рдЦреЗрдВ pubspec.yamlред

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:


рдПрдВрдбреНрд░реЙрдЗрдб рдФрд░ рд╕реНрдкрдВрджрди рдореЗрдВ рдЧреНрд░рд╛рдлрд┐рдХ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рдЖрдХрд╛рд░ рдХреА рддреБрд▓рдирд╛ред
Android рдШрдирддреНрд╡ рдХреНрд╡рд╛рд▓реАрдлрд╛рдпрд░рд╕реНрдкрдВрджрди рдкрд┐рдХреНрд╕реЗрд▓ рдЕрдиреБрдкрд╛рдд
ldpi0.75x
mdpi1.0x
hdpi1.5x
xhdpi2.0x
xxhdpi3.0x
xxxhdpi4.0x
рд╕рдВрд╕рд╛рдзрди рд▓реЗрдЖрдЙрдЯ рдЙрджрд╛рд╣рд░рдг:
images/my_icon.png       // Base: 1.0x image
images/2.0x/my_icon.png  // 2.0x image
images/3.0x/my_icon.png  // 3.0x image

рдХрд┐рд╕реА pubspec.yamlрдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрде рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг :
assets:
 - images/my_icon.jpeg

AssetImage рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг :
return AssetImage("images/a_dot_burr.jpeg");

рдкреНрд░рддреНрдпрдХреНрд╖ рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг asset:
@override
Widget build(BuildContext context) {
  return Image.asset("images/my_image.png");
}

рд╕рд╡рд╛рд▓:


рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХрд╣рд╛рдБ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВ? рдЙрдирдХрд╛ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреИрд╕реЗ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рдкрд▓рдХ рдЭрдкрдХрддреЗ рд╣реА рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЦрд╛рд╕ рдЬрдЧрд╣ рдирд╣реАрдВ рд╣реИред рдЙрдиреНрд╣реЗрдВ рдПрдХ рдЕрд▓рдЧ рд╡рд░реНрдЧ рдореЗрдВ рд╕реНрдерд┐рд░ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╣реИред рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП flutter_localifications рдпрд╛ l10n ред

рдЕрдВрддрд░:


Xamarin.Forms рдПрдХ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ resxред

рдЙрджрд╛рд╣рд░рдг:


рд╕рдВрдЧреНрд░рд╣рдг:
class Strings {
  static String welcomeMessage = "Welcome To Flutter";
}

рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП:
new Text(Strings.welcomeMessage)

рд╕реНрдерд╛рдиреАрдпрдХрд░рдг:
dependencies:
  # ...
  flutter_localizations:
    sdk: flutter
  intl: "^0.15.6"

import 'package:flutter_localizations/flutter_localizations.dart';

new MaterialApp(
 localizationsDelegates: [
   // Add app-specific localization delegate[s] here.
   GlobalMaterialLocalizations.delegate,
   GlobalWidgetsLocalizations.delegate,
 ],
 supportedLocales: [
    const Locale('en', 'US'), // English
    const Locale('he', 'IL'), // Hebrew
    // ... other locales the app supports
  ],
  // ...
)

рд╕рд╡рд╛рд▓:


рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓ рдХрд╣рд╛рдБ рд╣реИ?

рдЙрддреНрддрд░:


рд╕реНрдкрдВрджрди рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд╡рд┐рдХрд╛рд╕ рдХреЗ рдорд╛рд╣реМрд▓ рдореЗрдВ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдлрд╝рд╛рдЗрд▓ рдирд╣реАрдВ рд╣реИред рдирд┐рдХрдЯрддрдо рд╕рдорд╛рди рдлрд╝рд╛рдЗрд▓ - pubspec.yaml- рдореЗрдВ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдФрд░ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╡рд┐рд╡рд░рдг рдкрд░ рдирд┐рд░реНрднрд░рддрд╛рдПрдВ рд╣реИрдВред

рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдЬреАрд╡рди рдЪрдХреНрд░


рд╕рд╡рд╛рд▓:


рдЬреАрд╡рди рдЪрдХреНрд░ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓реЗрдВ?

рдЙрддреНрддрд░:


WidgetsBinding рдФрд░ didChangeAppLifecycleState () рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:


Flutter рдПрдВрдбреНрд░реЙрдЗрдб рдХреЛрдб рдореЗрдВ FlutterActivity рдФрд░ iOS рдореЗрдВ FlutterAppDelegate рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ , рдЗрд╕ рд╡рдЬрд╣ рд╕реЗ Flutter рдЗрдВрдЬрди рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕реНрдерд┐рддрд┐ рдХреЛ рдпрдерд╛рд╕рдВрднрд╡ рдЕрд╕рдВрдЧрдд рдмрдирд╛ рджреЗрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдХреЛ рдЕрднреА рднреА рд░рд╛рдЬреНрдп рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреБрдЫ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЬреАрд╡рди рдЪрдХреНрд░ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рд╣реИ:
  • рдирд┐рд╖реНрдХреНрд░рд┐рдп - рдпрд╣ рд╡рд┐рдзрд┐ рдХреЗрд╡рд▓ iOS рдореЗрдВ рд╣реИ, рдПрдВрдбреНрд░реЙрдЗрдб рдореЗрдВ рдХреЛрдИ рдПрдирд╛рд▓реЙрдЧ рдирд╣реАрдВ рд╣реИ;
  • рд░реЛрдХрд╛ рдЧрдпрд╛ - Android рдореЗрдВ onPause () рдХреЗ рд╕рдорд╛рди;
  • рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ - Android рдореЗрдВ onPostResume () рдХреЗ рд╕рдорд╛рди;
  • рдирд┐рд▓рдВрдмрд┐рдд - Android рдореЗрдВ onStop рдХреЗ рд╕рдорд╛рди, iOS рдореЗрдВ рдХреЛрдИ рдПрдирд╛рд▓реЙрдЧ рдирд╣реАрдВ рд╣реИред

рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП AppLifecycleStatus рдкреНрд░рд▓реЗрдЦрди рджреЗрдЦреЗрдВ ред

рдЙрджрд╛рд╣рд░рдг:


import 'package:flutter/widgets.dart';

class LifecycleWatcher extends StatefulWidget {
  @override
  _LifecycleWatcherState createState() => _LifecycleWatcherState();
}

class _LifecycleWatcherState extends State<LifecycleWatcher> with WidgetsBindingObserver {
  AppLifecycleState _lastLifecycleState;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    setState(() {
      _lastLifecycleState = state;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (_lastLifecycleState == null)
      return Text('This widget has not observed any lifecycle changes.', textDirection: TextDirection.ltr);

    return Text('The most recent lifecycle state this widget observed was: $_lastLifecycleState.',
        textDirection: TextDirection.ltr);
  }
}

void main() {
  runApp(Center(child: LifecycleWatcher()));
}

рд▓реЗрдЖрдЙрдЯ


рд╕рд╡рд╛рд▓:


StackLayout рдХрд╛ рдПрдирд╛рд▓реЙрдЧ рдХреНрдпрд╛ рд╣реИ ?

рдЙрддреНрддрд░:


рдКрд░реНрдзреНрд╡рд╛рдзрд░ рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рд╕рд╛рде рд╕реНрдЯреИрдХрд▓реИрдЯ рдХрд╛ рдПрдирд╛рд▓реЙрдЧ рдХреЙрд▓рдо рд╣реИ , рдФрд░ рдХреНрд╖реИрддрд┐рдЬ - рдкрдВрдХреНрддрд┐ рдХреЗ рд╕рд╛рде ред

рдЙрджрд╛рд╣рд░рдг:


рд╕реНрддрдВрдн:
@override
Widget build(BuildContext context) {
  return new Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      new Text('Column One'),
      new Text('Column Two'),
      new Text('Column Three'),
      new Text('Column Four'),
    ],
  );
}

рдкрдВрдХреНрддрд┐:
@override
Widget build(BuildContext context) {
  return new Row(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      new Text('Row One'),
      new Text('Row Two'),
      new Text('Row Three'),
      new Text('Row Four'),
    ],
  );
}

рд╕рд╡рд╛рд▓:


рдЧреНрд░рд┐рдб рдХрд╛ рдПрдирд╛рд▓реЙрдЧ рдХреНрдпрд╛ рд╣реИ ?

рдЙрддреНрддрд░:


рдЗрд╕ рдЧреНрд░рд┐рдб ред

рдЙрджрд╛рд╣рд░рдг:


GridView.count(
  // Create a grid with 2 columns. If you change the scrollDirection to
  // horizontal, this would produce 2 rows.
  crossAxisCount: 2,
  // Generate 100 widgets that display their index in the List
  children: List.generate(100, (index) {
    return Center(
      child: Text(
        'Item $index',
        style: Theme.of(context).textTheme.headline,
      ),
    );
  }),
);

рд╕рд╡рд╛рд▓:


рд╕реНрдХреНрд░реЙрд▓рд╡реНрдпреВ рдХрд╛ рдПрдирд╛рд▓реЙрдЧ рдХреНрдпрд╛ рд╣реИ ?

рдЙрддреНрддрд░:


рдирд┐рдХрдЯрддрдо рдПрдирд╛рд▓реЙрдЧ SingleChildScrollView рд╣реИ ред рд▓реЗрдХрд┐рди рд╕реНрдкрдВрджрди рдЕрдХреНрд╕рд░ рд░реЗрдВрдЧрдиреЗ рд╡рд╛рд▓реА рд╕рд╛рдордЧреНрд░реА рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП рд▓рд┐рд╕реНрдЯ рд╡реНрдпреВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ ред

рдЙрджрд╛рд╣рд░рдг:


SingleChildScrollView:
@override
Widget build(BuildContext context) {
  return new SingleChildScrollView(
    child: new Text('Long Content'),
  );
}

рд╕реВрдЪреА рджреГрд╢реНрдп:
@override
Widget build(BuildContext context) {
  return new ListView(
    children: <Widget>[
      new Text('Row One'),
      new Text('Row Two'),
      new Text('Row Three'),
      new Text('Row Four'),
    ],
  );
}

рдЗрд╢рд╛рд░реЗ рд╕реЗ рд╕рдВрднрд╛рд▓рдирд╛


рд╕рд╡рд╛рд▓:


рдХреИрд╕реЗ рдХрд░реЗрдВ рдХреНрд▓рд┐рдХ рдХреЛ рд╣реИрдВрдбрд▓?

рдЙрддреНрддрд░:


рдпрджрд┐ рд╡рд┐рдЬреЗрдЯ рд╡рд┐рдзрд┐ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ onPressed, рддреЛ рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреНрд▓рд┐рдХ рдХреЛ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдиреНрдпрдерд╛, рдпрд╣ GestureDetector рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред

рдЙрджрд╛рд╣рд░рдг:


onPressed:
@override
Widget build(BuildContext context) {
  return new RaisedButton(
      onPressed: () {
        print("click");
      },
      child: new Text("Button"));
}

GestureDetector:
class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(
      child: new GestureDetector(
        child: new FlutterLogo(
          size: 200.0,
        ),
        onTap: () {
          print("tap");
        },
      ),
    ));
  }
}

рд╕рд╡рд╛рд▓:


рдЗрд╢рд╛рд░реЛрдВ рдХреЛ рдХреИрд╕реЗ рд╕рдВрднрд╛рд▓реЗрдВ?

рдЙрддреНрддрд░:


GestureDetector рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред рд╡реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ:

рдирд▓ рдЯреЛрдЯреА



рджреЛ рдмрд╛рд░ рдЯреИрдк



рджреЗрд░ рддрдХ рджрдмрд╛рдирд╛



рд▓рдВрдмрд╡рдд рдЦреАрдВрдЪреЗрдВ



рдХреНрд╖реИрддрд┐рдЬ рдЦреАрдВрдЪреЗрдВ



рдЙрджрд╛рд╣рд░рдг:


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);
}

class SampleApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(
          child: new GestureDetector(
            child: new RotationTransition(
                turns: curve,
                child: new FlutterLogo(
                  size: 200.0,
                )),
            onDoubleTap: () {
              if (controller.isCompleted) {
                controller.reverse();
              } else {
                controller.forward();
              }
            },
        ),
    ));
  }
}

рд╕реВрдЪреА рджреГрд╢реНрдп рдФрд░ рдПрдбреЗрдкреНрдЯрд░


рд╕рд╡рд╛рд▓:


ListView рдХрд╛ рдПрдирд╛рд▓реЙрдЧ рдХреНрдпрд╛ рд╣реИ ?

рдЙрддреНрддрд░:


рд╕реВрдЪреА рджреГрд╢реНрдп ред

рдЕрдВрддрд░:


Xamarin.Forms рдореЗрдВ, рдЖрдкрдХреЛ рдПрдХ ViewCell рдФрд░ (рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░) DataTemplateSelector рдмрдирд╛рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ ListView рдореЗрдВ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред рд╕реНрдкрдВрджрди рдореЗрдВ, рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдЧреЗрдЯреНрд╕ рдХреА рдПрдХ рд╕реВрдЪреА рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЙрджрд╛рд╣рд░рдг:


import 'package:flutter/material.dart';

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

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

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

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

class _SampleAppPageState extends State<SampleAppPage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Sample App"),
      ),
      body: new ListView(children: _getListData()),
    );
  }

  _getListData() {
    List<Widget> widgets = [];
    for (int i = 0; i < 100; i++) {
      widgets.add(new Padding(padding: new EdgeInsets.all(10.0), child: new Text("Row $i")));
    }
    return widgets;
  }
}

рд╕рд╡рд╛рд▓:


рдХрд┐рд╕ рддрддреНрд╡ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛?

рдЙрддреНрддрд░:


рд╕реНрдкрдВрджрди рдореЗрдВ, рдПрдХ рддрддреНрд╡ рд╡рд┐рдЬреЗрдЯ рдХреЛ рд╕реНрд╡рдпрдВ рдХреНрд▓рд┐рдХ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЕрдВрддрд░:


Xamarin.Forms рдЖрдорддреМрд░ рдкрд░ ItemTapped рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ ред

рдЙрджрд╛рд╣рд░рдг:


import 'package:flutter/material.dart';

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

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

class SampleAppPage extends StatefulWidget {
  SampleAppPage({Key key}) : super(key: key);

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

class _SampleAppPageState extends State<SampleAppPage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("Sample App"),
      ),
      body: new ListView(children: _getListData()),
    );
  }

  _getListData() {
    List<Widget> widgets = [];
    for (int i = 0; i < 100; i++) {
      widgets.add(new GestureDetector(
        child: new Padding(
            padding: new EdgeInsets.all(10.0),
            child: new Text("Row $i")),
        onTap: () {
          print('row tapped');
        },
      ));
    }
    return widgets;
  }
}

рд╕рд╡рд╛рд▓:


рд▓рд┐рд╕реНрдЯ рд╡реНрдпреВ рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдХреИрд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ ?

рдЙрддреНрддрд░:


рдбреЗрдЯрд╛ рд╕реВрдЪреА рдФрд░ рдХреЙрд▓ рддрд╛рдЬрд╝рд╛ рдХрд░реЗрдВ setState()ред

рдЕрдВрддрд░:


Xamarin.Forms рдПрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ ItemsSource рдЗрд╕ рдХреЗ рд▓рд┐рдП ред рд╕реНрдкрдВрджрди рдореЗрдВ, setState()рд╡рд┐рдЬреЗрдЯ рдХреЗ рдмрд╛рдж рдлрд┐рд░ рд╕реЗ рдлрд┐рд░ рд╕реЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЙрджрд╛рд╣рд░рдг:


import 'package:flutter/material.dart';

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

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> {
  List widgets = [];

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < 100; i++) {
      widgets.add(getRow(i));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: ListView(children: widgets),
    );
  }

  Widget getRow(int i) {
    return GestureDetector(
      child: Padding(
        padding: EdgeInsets.all(10.0),
        child: Text("Row $i"),
      ),
      onTap: () {
        setState(() {
          widgets = List.from(widgets);
          widgets.add(getRow(widgets.length + 1));
          print('row $i');
        });
      },
    );
  }
}

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:


рдПрдХ рд╕реВрдЪреА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ ListView.Builder рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд╢рдВрд╕рд┐рдд рд╣реИ ред

рдЙрджрд╛рд╣рд░рдг:


import 'package:flutter/material.dart';

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

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> {
  List widgets = [];

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < 100; i++) {
      widgets.add(getRow(i));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: ListView.builder(
        itemCount: widgets.length,
        itemBuilder: (BuildContext context, int position) {
          return getRow(position);
        },
      ),
    );
  }

  Widget getRow(int i) {
    return GestureDetector(
      child: Padding(
        padding: EdgeInsets.all(10.0),
        child: Text("Row $i"),
      ),
      onTap: () {
        setState(() {
          widgets.add(getRow(widgets.length + 1));
          print('row $i');
        });
      },
    );
  }
}

рдЯреЗрдХреНрд╕реНрдЯ


рд╕рд╡рд╛рд▓:


рдХрд╕реНрдЯрдо рдлреЛрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рдлрд╝реЙрдиреНрдЯ рдлрд╝рд╛рдЗрд▓ рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдмрд╕ рдПрдХ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдбрд╛рд▓рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ (рдЕрдкрдиреЗ рд▓рд┐рдП рдПрдХ рдирд╛рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪреЗрдВ) рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрде рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ pubspec.yamlред

рдЙрджрд╛рд╣рд░рдг:


fonts:
   - family: MyCustomFont
     fonts:
       - asset: fonts/MyCustomFont.ttf
       - style: italic

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: Text("Sample App"),
    ),
    body: Center(
      child: Text(
        'This is a custom font text',
        style: TextStyle(fontFamily: 'MyCustomFont'),
      ),
    ),
  );
}

рд╕рд╡рд╛рд▓:


рдЯреЗрдХреНрд╕реНрдЯ рд╡рд┐рдЬреЗрдЯ рдХреИрд╕реЗ рд╕реНрдЯрд╛рдЗрд▓ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ:

  • рд░рдВрдЧ;
  • рд╕рдЬрд╛рд╡рдЯ;
  • decorationColor;
  • decorationStyle;
  • рдлрд╝реЙрдиреНрдЯ рдкрд░рд┐рд╡рд╛рд░;
  • рдлрд╝реЙрдиреНрдЯ рдЖрдХрд╛рд░;
  • рдлрд╝реЙрдиреНрдЯ рд╢реИрд▓реА;
  • рдлрд╝реЙрдиреНрдЯ рд╡рдЬрди;
  • рд╣реИрд╢ рдХреЛрдб;
  • рдКрдВрдЪрд╛рдИ;
  • рд╡рд╛рд░рд┐рд╕;
  • рдкрддреНрд░ рдЕрдВрддрд░рд╛рд▓;
  • textBaseline;
  • wordSpacingред

рд╕рд╡рд╛рд▓:


рдкреНрд▓реЗрд╕рд╣реЛрд▓реНрдбрд░ рдХреЗ рд╕рдорддреБрд▓реНрдп рдХреНрдпрд╛ рд╣реИ ?

рдЙрддреНрддрд░:


HintText рд╕рдВрдкрддреНрддрд┐ рдХреА InputDecoration ред

рдЙрджрд╛рд╣рд░рдг:


body: new Center(
  child: new TextField(
    decoration: new InputDecoration(hintText: "This is a hint"),
  )
)

рд╕рд╡рд╛рд▓:


рд╕рддреНрдпрд╛рдкрди рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдХреИрд╕реЗ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдП?

рдЙрддреНрддрд░:


рд╕рднреА рдЙрд╕реА рдХреЗ рд╕рд╛рде InputDecoration рдФрд░ рдЙрд╕рдХрд╛ рд░рд╛рдЬреНрдпред

рдЙрджрд╛рд╣рд░рдг:


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> {
  String _errorText;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Sample App"),
      ),
      body: Center(
        child: TextField(
          onSubmitted: (String text) {
            setState(() {
              if (!isEmail(text)) {
                _errorText = 'Error: This is not an email';
              } else {
                _errorText = null;
              }
            });
          },
          decoration: InputDecoration(hintText: "This is a hint", errorText: _getErrorText()),
        ),
      ),
    );
  }

  _getErrorText() {
    return _errorText;
  }

  bool isEmail(String emailString) {
    String emailRegexp =
        r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';

    RegExp regExp = RegExp(emailRegexp);

    return regExp.hasMatch(emailString);
  }
}

рд╕реНрдкрдВрджрди рдкреНрд▓рдЧрдЗрдиреНрд╕


рд╕рд╡рд╛рд▓:


GPS рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рдЬрд┐рдпреЛрд▓реЛрдХреЗрд╢рди рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рд╕рд╡рд╛рд▓:


рдХреИрдорд░реЗ рддрдХ рдХреИрд╕реЗ рдкрд╣реБрдВрдЪреЗрдВ?

рдЙрддреНрддрд░:


Image_picker рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рд╕рд╡рд╛рд▓:


рдлреЗрд╕рдмреБрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓реЙрдЧ рдЗрди рдХреИрд╕реЗ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


Flutter_facebook_login рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рд╕рд╡рд╛рд▓:


рдлрд╛рдпрд░рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


Firebase рдлрд╝реНрд▓рдЯрд░ рдкреНрд░рдердо рдкрд╛рд░реНрдЯреА рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ :

рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдб


рд╕рд╡рд╛рд▓:


рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреЛрдб рдХрд┐рд╕ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдкрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реИ?

рдЙрддреНрддрд░:


рдереАрдо рдпрд╛ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╡рд░реНрдЧ platformрдореЗрдВ рдлрд╝реАрд▓реНрдб рдХреНрд▓рд╛рд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдЙрджрд╛рд╣рд░рдг:


рдЦреЗрдд platform:
if (Theme.of(context).platform == TargetPlatform.iOS) {
  return 'iOS';
} else if (Theme.of(context).platform == TargetPlatform.android) {
  return 'android';
} else if (Theme.of(context).platform == TargetPlatform.fuchsia) {
  return 'fuchsia';
} else {
  return 'not recognised ';
}

рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреНрд▓рд╛рд╕:
if (Platform.isIOS) {
  return 'iOS';
} else if (Platform.isAndroid) {
  return 'android';
} else if (Platform.isFuchsia) {
  return 'fuchsia';
} else {
  return 'not recognised ';
}

рд╕рд╡рд╛рд▓:


рджреЗрд╢реА рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреЛрдб рдХреИрд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рд╡рд╛рдпрд╛ рдореЗрдерд╛рдВрдЪреЗрд▓ ред

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:


рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдБ ред

рдбрд┐рдмрдЧрд┐рдВрдЧ


рд╕рд╡рд╛рд▓:


рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреАрдмрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реЗ рдЯреВрд▓ рд╣реИрдВ?

рдЙрддреНрддрд░:


DevTools ред

рд╕рд╡рд╛рд▓:


рдХреИрд╕реЗ рдХрд░реЗрдВ hot reload?

рдЙрддреНрддрд░:


рдпрджрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ IntelliJ IDE, Android Studio рдпрд╛ VSCode рд╕реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ тМШs/ctrl-sрдЖрдЗрдХрди рдкрд░ рд╕рдВрдпреЛрдЬрди рдпрд╛ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ hot reloadред рдпрджрд┐ рдЯрд░реНрдорд┐рдирд▓ рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдПрдХ рдкрддреНрд░ рджрд░реНрдЬ рдХрд░рдХреЗ rред

рд╕рд╡рд╛рд▓:


рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдбреЗрд╡рд▓рдкрд░ рдореЗрдиреВ рдХреИрд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


рдпрджрд┐ рд▓реЙрдиреНрдЪ рдЖрдИрдбреАрдИ рд╕реЗ рдерд╛, рддреЛ рдЖрдИрдбреАрдИ рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗред рдпрджрд┐ рдХрдВрд╕реЛрд▓ рд╕реЗ, рддреЛ h рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:


рдЖрджреЗрд╢реЛрдВ рдХреА рдкреВрд░реА рд╕реВрдЪреА:

рдЕрдзрд┐рдирд┐рдпрдордЯрд░реНрдорд┐рдирд▓ рдореЗрдВ рдЯреАрдордХрд╛рд░реНрдп рдФрд░ рдХреНрд╖реЗрддреНрд░
рд╡рд┐рдЬреЗрдЯ рдкрджрд╛рдиреБрдХреНрд░рдоwdebugDumpApp ()
рд╡реГрдХреНрд╖ рдХрд╛ рдкреЗрдбрд╝рдЯреАdebugDumpRenderTree ()
рдкрд░рддреЗрдВрдПрд▓debugDumpLayerTree ()
рд╕рд░рд▓ рдЙрдкрдпреЛрдЧрдПрд╕ (рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рдСрд░реНрдбрд░) рдпрд╛ рдпреВ (рдЙрд▓рдЯрд╛ рд╣рд┐рдЯ рдЯреЗрд╕реНрдЯ рдСрд░реНрдбрд░)debugDumpSemantics ()
рд╡рд┐рдЬреЗрдЯ рдЗрдВрд╕реНрдкреЗрдХреНрдЯрд░рдореИрдВWidgetsApp.showWidgetInspectorOverride
рдирд┐рд░реНрдорд╛рдг рд▓рд╛рдЗрдиреЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВрдкреАdebugPaintSizeEnabled
рд╡рд┐рднрд┐рдиреНрди рдУрдПрд╕ рдХрд╛ рдЕрдиреБрдХрд░рдгрдУdefaultTargetPlatform
рдкреНрд░рджрд░реНрд╢рдирдкреАWidgetsAppред showPerformanceOverlay
рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдлрд╝реНрд▓рд░реНрдЯ рдХрд░реЗрдВрд░реЛрдВ
рдЖрд╡реЗрджрди рдмрдВрджрдХреНрд╖

рд╕реНрдерд╛рдиреАрдп рднрдВрдбрд╛рд░


рд╕рд╡рд╛рд▓:


key-valueрдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдбреЗрдЯрд╛ рдХреИрд╕реЗ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВ ?

рдЙрддреНрддрд░:


рд╢реЗрдЕрд░_рдкреЙрдЗрдВрдЯрд░реНрд╕ рдкреНрд▓рдЧрдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдЕрдВрддрд░:


Xamarin рдореЗрдВ .Forms рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ Xam.Plugins.Settingsред

рдЙрджрд╛рд╣рд░рдг:


рдХрдиреЗрдХреНрд╢рди рдирд┐рд░реНрднрд░рддрд╛:
dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^0.4.3

рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП:
SharedPreferences prefs = await SharedPreferences.getInstance();
_counter = prefs.getInt('counter');
prefs.setInt('counter', ++_counter);
setState(() {
  _counter = _counter;
});

рд╕рд╡рд╛рд▓:


рдЬрдЯрд┐рд▓ рдбреЗрдЯрд╛ рдХреИрд╕реЗ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВ?

рдЙрддреНрддрд░:


Sqflite рдпрд╛ hive рдЬреИрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред

рдпрд╣рд╛рдБ рд╢рд╛рдпрдж рдореВрд▓ рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рд╣реИрдВред рдпрд╣ рд╡реНрдпрд╛рдЦреНрдпрд╛рдУрдВ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рд╕рдорд╛рдкрди рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рд╡реЗ рдЗрд╕ рдврд╛рдВрдЪреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рдереЗред рд╢рд╛рдпрдж рдЖрдкрдиреЗ рднреА рдлрд╝реНрд▓рдЯрд░ рдкрд░ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рдФрд░ рдлрд╝реНрд▓рдЯрд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдПрдХ рдЕрдиреБрдХреВрд▓ рд╕рдореБрджрд╛рдп рдореЗрдВ рдЖрдкрдХреЛ рднрд░реНрддреА рдХрд┐рдпрд╛ред рдФрд░ рдореИрдВ рд╕рдореБрджрд╛рдп рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреА рджреБрдирд┐рдпрд╛ рдХреЛ рдмреЗрд╣рддрд░ рдЬрдЧрд╣ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирдП рд▓реЗрдЦреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪреВрдВрдЧрд╛ред рдЕрдкрдиреЗ рд░реВрдкреЛрдВ рдХреЛ рдЬрд╝рдореАрд░ рдирд╣реАрдВ рддреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ!

All Articles