рдпрд╣ рдлрд╝реНрд▓рдЯрд░ рдкреНрд░рд▓реЗрдЦрди рдХреА рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд╛ рдЕрдВрддрд┐рдо рд╣рд┐рд╕реНрд╕рд╛ рд╣реИ рдЬреЛ Xamarin.Forms рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдЕрдм рдХреБрдЫ рдирдпрд╛ рд╕реАрдЦрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ! рдХрдЯреМрддреА рдХреЗ рддрд╣рдд, рдЖрдк рдЕрдкрдиреЗ рдЖрдк рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдЬрд╛рдирдХрд╛рд░реА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдПрдХ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдлреНрд░реЗрдорд╡рд░реНрдХ рд╕реЗ рджреВрд╕рд░реЗ рдореЗрдВ рдЬрд╛рдиреЗ рдХреЗ рд▓рд╛рдпрдХ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдХрд┐рддрдирд╛ рд╕рдордп рд▓рдЧреЗрдЧрд╛ред
рдпрджрд┐ рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ рдпрд╛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдордВрдЪ рдХреЗ рд▓рд┐рдП рджреЗрд╢реА рд╡рд┐рдХрд╛рд╕ рдХрд╛ рдЕрдиреБрднрд╡ рд╣реИ, рддреЛ рдореИрдВ рдЕрдиреНрдп рднрд╛рдЧреЛрдВ рдореЗрдВ рджреЗрдЦрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ:рд╕реНрдкрдВрджрдиред рднрд╛рдЧ 1. Android рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдПрд╕реНрдкрдВрджрдиред рднрд╛рдЧ 2. iOS рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдПрд╕реНрдкрдВрджрдиред рднрд╛рдЧ 3. рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдореВрд▓рд╕реНрдкрдВрджрди рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП ред рднрд╛рдЧ 4. рд╕реНрдкрдВрджрди рд╡реЗрдм рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдПред рднрд╛рдЧ 5. рдЬрд╝рд╛рдорд░реАрди рдХреЗ рд▓рд┐рдПрд╕рд╛рдордЧреНрд░реА:
- рдкрд░рд┐рдпреЛрдЬрдирд╛
- Views
- Async UI
- Layouts
- ListView
- рдЯреЗрдХреНрд╕реНрдЯ
- рд╕реНрдкрдВрджрди рдкреНрд▓рдЧрдЗрдиреНрд╕
- рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдб
- рдбрд┐рдмрдЧрд┐рдВрдЧ
- рд╕реНрдерд╛рдиреАрдп рднрдВрдбрд╛рд░
рдкрд░рд┐рдпреЛрдЬрдирд╛
рд╕рд╡рд╛рд▓:
рдкреНрд░рд╡реЗрд╢ рдмрд┐рдВрджреБ рдХрд╣рд╛рдВ рд╣реИ?рдЙрддреНрддрд░:
рдХрд╛рд░реНрдп main()
редрдЕрдВрддрд░:
Xamarin.Forms рдореЗрдВ рдпрд╣ рд╣реИ LoadApplication(new App());
редрдЙрджрд╛рд╣рд░рдг:
void main() {
runApp(new MyApp());
}
рд╕рд╡рд╛рд▓:
рдкреЗрдЬ рдпрд╛ рдПрд▓рд┐рдореЗрдВрдЯ
рдХреИрд╕реЗ рдмрдирд╛рдПрдВ ?рдЙрддреНрддрд░:
Flutter рдореЗрдВ рдкреЗрдЬ рдФрд░ рдПрд▓рд┐рдореЗрдВрдЯ рдХреА рдХреЛрдИ рдЕрд╡рдзрд╛рд░рдгрд╛ рдирд╣реАрдВ рд╣реИ ред рд╕рднреА рдШрдЯрдХ рд╡рд┐рдЬреЗрдЯ рд╣реИрдВред рд╕реНрдкрдВрджрди рдореЗрдВ 2 рдкреНрд░рдХрд╛рд░ рдХреЗ рд╡рд┐рдЬреЗрдЯ рд╣реИрдВ: рд╕реНрдЯреЗрдЯрд▓реЗрд╕рд╡рд┐рдЬреЗрдЯ рдФрд░ рд╕реНрдЯреЗрдЯрдлреБрд▓рд╡реЗрдЯ ред рд╡реЗ рдЙрд╕реА рддрд░рд╣ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдПрдХрдорд╛рддреНрд░ рдЕрдВрддрд░ рдкреНрд░рддрд┐рдкрд╛рджрди рд░рд╛рдЬреНрдп рдореЗрдВ рд╣реИредрдЕрдВрддрд░:
рд╕реНрдЯреЗрдЯрд▓реЗрд╕рд╡рд┐рдЬреЗрдЯ рдореЗрдВ рдПрдХ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рд╕реНрдерд┐рддрд┐ рд╣реИред рдкрд╛рда, рд▓реЛрдЧреЛ рдЗрддреНрдпрд╛рджрд┐ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИред рдЙрдиред рдпрджрд┐ рд╕реНрдХреНрд░реАрди рдкрд░ рдореМрдЬреВрдж рддрддреНрд╡ рдкреВрд░реЗ рдбрд┐рд╕реНрдкреНрд▓реЗ рдЯрд╛рдЗрдо рдХреЗ рджреМрд░рд╛рди рдирд╣реАрдВ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рд┐рдП, рддреЛ рдпрд╣ рдЖрдкрдХреЛ рд╕реВрдЯ рдХрд░рддрд╛ рд╣реИред рдЗрд╕реЗ рд╕реНрдЯреЗрдЯрдлреБрд▓ рд╡рд┐рдЬреЗрдЯ рдХреЗ рд▓рд┐рдП рдХрдВрдЯреЗрдирд░ рдХреЗ рд░реВрдк рдореЗрдВ рднреА рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИредStatefulWidget рдореЗрдВ рд░рд╛рдЬреНрдп рд╡рд░реНрдЧ рд╣реИ , рдЬреЛ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдХреБрдЫ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░рддреЗ рд╕рдордп рд╕реНрдХреНрд░реАрди рдкрд░ рдПрдХ рддрддреНрд╡ рдХреЛ рдмрджрд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ (рд╕рд░реНрд╡рд░ рд╕реЗ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЖрдИ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдПрдХ рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛, рдЖрджрд┐) - рдпрд╣ рдЖрдкрдХрд╛ рд╡рд┐рдХрд▓реНрдк рд╣реИредрдЙрджрд╛рд╣рд░рдг:
StatelessWidget:class MyApp extends StatelessWidget {
@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(
title: new Text(widget.title),
),
body: new Center(
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 {
@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> {
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 {
@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 рдиреЗрд╡рд┐рдЧреЗрд╢рдирдкреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ редрдлрд╝реНрд▓рдЯрд░ рдореЗрдВ рджреЛ рдиреЗрд╡рд┐рдЧреЗрд╢рди рддрд░реАрдХреЗ рд╣реИрдВ рдЬреЛ рдХрд┐ рдиреЗрд╡рд┐рдЧреЗрд╢рдирдкреЗрдЬ рдХреЗ рд╕рдорд╛рди рд╣реИрдВ :- рдорд╛рд░реНрдЧ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╛рдореЛрдВ рдХреЛ рдореИрдк рдХрд░реЗрдВ ;
- рд╕реАрдзреЗ рд░реВрдЯ рдкрд░ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░реЗрдВ ред
рдиреЗрд╡рд┐рдЧреЗрдЯрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдзрдХреНрдХрд╛ () рдпрд╛ () рдкреЙрдк рдорд╛рд░реНрдЧ рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПредрдЙрджрд╛рд╣рд░рдг:
void main() {
runApp(CupertinoApp(
home: MyAppHome(),
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
редрдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:
рдПрдВрдбреНрд░реЙрдЗрдб рдФрд░ рд╕реНрдкрдВрджрди рдореЗрдВ рдЧреНрд░рд╛рдлрд┐рдХ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рдЖрдХрд╛рд░ рдХреА рддреБрд▓рдирд╛редрд╕рдВрд╕рд╛рдзрди рд▓реЗрдЖрдЙрдЯ рдЙрджрд╛рд╣рд░рдг: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: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'),
const Locale('he', 'IL'),
],
)
рд╕рд╡рд╛рд▓:
рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓ рдХрд╣рд╛рдБ рд╣реИ?рдЙрддреНрддрд░:
рд╕реНрдкрдВрджрди рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рд╡рд┐рдХрд╛рд╕ рдХреЗ рдорд╛рд╣реМрд▓ рдореЗрдВ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдлрд╝рд╛рдЗрд▓ рдирд╣реАрдВ рд╣реИред рдирд┐рдХрдЯрддрдо рд╕рдорд╛рди рдлрд╝рд╛рдЗрд▓ - 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(
crossAxisCount: 2,
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 {
@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 {
@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 {
@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 {
@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 {
@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 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВредрдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА:
рдЖрджреЗрд╢реЛрдВ рдХреА рдкреВрд░реА рд╕реВрдЪреА:рд╕реНрдерд╛рдиреАрдп рднрдВрдбрд╛рд░
рд╕рд╡рд╛рд▓:
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
рдЬреИрд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ редрдпрд╣рд╛рдБ рд╢рд╛рдпрдж рдореВрд▓ рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рд╣реИрдВред рдпрд╣ рд╡реНрдпрд╛рдЦреНрдпрд╛рдУрдВ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рд╕рдорд╛рдкрди рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рд╡реЗ рдЗрд╕ рдврд╛рдВрдЪреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рдереЗред рд╢рд╛рдпрдж рдЖрдкрдиреЗ рднреА рдлрд╝реНрд▓рдЯрд░ рдкрд░ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рдФрд░ рдлрд╝реНрд▓рдЯрд░ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рдПрдХ рдЕрдиреБрдХреВрд▓ рд╕рдореБрджрд╛рдп рдореЗрдВ рдЖрдкрдХреЛ рднрд░реНрддреА рдХрд┐рдпрд╛ред рдФрд░ рдореИрдВ рд╕рдореБрджрд╛рдп рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдФрд░ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреА рджреБрдирд┐рдпрд╛ рдХреЛ рдмреЗрд╣рддрд░ рдЬрдЧрд╣ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирдП рд▓реЗрдЦреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪреВрдВрдЧрд╛ред рдЕрдкрдиреЗ рд░реВрдкреЛрдВ рдХреЛ рдЬрд╝рдореАрд░ рдирд╣реАрдВ рддреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ!