[Di dermaga] Berkibar. Bagian 5. Untuk Pengembang Xamarin

Ini adalah bagian terakhir dari interpretasi singkat dokumentasi Flutter yang akan berguna bagi pengembang Xamarin. Mengingat situasi saat ini, sekaranglah saatnya untuk mempelajari sesuatu yang baru! Di bawah potongan, Anda dapat menemukan informasi yang cukup untuk diri Anda sendiri untuk menilai apakah perlu bergerak dari satu kerangka kerja lintas platform ke kerangka kerja lainnya dan berapa lama waktu yang dibutuhkan.



Jika informasi ini tidak cukup atau Anda memiliki pengalaman dalam pengembangan asli untuk platform tertentu, maka saya sarankan untuk melihat bagian lain:

Flutter. Bagian 1. Untuk pengembang Android
Flutter. Bagian 2. Untuk pengembang iOS
Flutter. Bagian 3. Untuk pengembang React Native
Flutter. Bagian 4. Untuk pengembang web
Flutter. Bagian 5. Untuk Pengembang Xamarin

Kandungan:


  1. Proyek

  2. Views



  3. Async UI





  4. Layouts



  5. ListView

  6. Teks

  7. Flutter Plugins

  8. Kode khusus platform

  9. Debugging

  10. Penyimpanan lokal



Proyek


Pertanyaan:


Di mana titik masuknya?

Menjawab:


Fungsi main().

Perbedaan:


Di Xamarin LoadApplication(new App());. Bentuk ini .

Contoh:


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

Pertanyaan:


Bagaimana cara membuat Halaman atau Elemen ?

Menjawab:


Flutter tidak memiliki konsep Halaman dan Elemen . Semua komponen adalah widget. Flutter memiliki 2 jenis widget: StatelessWidget dan StatefulWidget . Mereka bekerja dengan cara yang sama, satu-satunya perbedaan adalah dalam kondisi rendering.

Perbedaan:


StatelessWidget memiliki status yang tidak dapat diubah. Cocok untuk menampilkan teks, logo, dll. Itu jika elemen pada layar tidak boleh berubah selama seluruh waktu tampilan, maka itu cocok untuk Anda. Ini juga dapat digunakan sebagai wadah untuk widget stateful.

StatefulWidget memiliki kelas Negara , yang menyimpan informasi tentang keadaan saat ini. Jika Anda ingin mengubah elemen di layar saat melakukan beberapa tindakan (respons datang dari server, pengguna mengklik tombol, dll.) - ini adalah pilihan Anda.

Contoh:


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

Tampilan


Pertanyaan:


Bagaimana cara mengatur widget? Apa yang setara dengan XAMLfile?

Menjawab:


Di Flutter, tata letak dilakukan langsung dalam kode menggunakan pohon widget.

Perbedaan:


Dalam Xamarin.Forms, tata letak yang paling sering dilakukan dalam XAMLfile. Flutter tidak memiliki padanan.

Informasi tambahan:


Daftar widget dapat dilihat di sini .

Contoh:


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

Pertanyaan:


Bagaimana cara menambah atau menghapus widget melalui kode?

Menjawab:


Dengan memperbarui keadaan widget induk dan kemudian membangun kembali pohon widget.

Perbedaan:


Dalam Xamarin. Bentuk, ini dapat dilakukan dengan menggunakan properti Contentelemen atau metode Add()dan Remove().

Contoh:


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

Pertanyaan:


Bagaimana cara menghidupkan widget?

Menjawab:


Menggunakan kelas Animation dan AnimationController .

Perbedaan:


Xamarin.Form menggunakan ViewExtensions dan metode seperti FadeToatau TranslateTo.

Informasi tambahan:


Baca lebih lanjut tentang animasi di sini .

Contoh:


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

Pertanyaan:


Cara menggambar di layar?

Menjawab:


Menggunakan kelas CustomPaint dan CustomPainter .

Perbedaan:


Xamarin.Forms menggunakan SkiaSharp pihak ketiga . Dalam Flutter, Skia Canvas digunakan langsung dari kotak.

Contoh:


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

Pertanyaan:


Bagaimana cara mengubah transparansi?

Menjawab:


Menggunakan widget Opacity .

Perbedaan:


Xamarin.Forms menggunakan Opacity of VisualElement . Di Flutter, Anda hanya perlu membungkus widget yang diinginkan dalam Opacity .

Pertanyaan:


Bagaimana cara membuat widget khusus?

Menjawab:


Buat mereka di dalam satu (bukan warisan).

Perbedaan:


Di Xamarin.Forms, Anda bisa mewarisi dari VisualElement yang menarik minat kami dan menambahkan logika Anda sendiri. Di Flutter, widget selalu diwarisi dari StatelessWidget dan StatefulWidget . Itu Anda perlu membuat widget baru dan menggunakan set widget yang diperlukan di dalamnya sebagai parameter atau bidang.

Contoh:


class CustomButton extends StatelessWidget {
  final String label;

  CustomButton(this.label);

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

Navigasi


Pertanyaan:


Bagaimana cara menavigasi antar layar?

Menjawab:


Untuk menavigasi antara layar, kelas Navigator dan Rute digunakan .

Perbedaan:


Xamarin.Forms menggunakan NavigationPage .

Flutter memiliki dua metode navigasi yang mirip dengan NavigationPage :

  1. Petakan nama untuk menggambarkan Rute ;
  2. Navigasi langsung ke Rute .

Navigator dapat melakukan push () atau pop () ke rute yang Anda tentukan.

Contoh:


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

Pertanyaan:


Bagaimana cara menavigasi ke aplikasi pihak ketiga?

Menjawab:


Menggunakan implementasi asli melalui MethodChannel atau url_launcher Plugin .

Async ui


Pertanyaan:


Apa yang setara dengan Device.BeginInvokeOnMainThread () ? Bagaimana cara mengeksekusi kode secara tidak sinkron?

Menjawab:


Dart mengimplementasikan model eksekusi single-threaded yang berjalan pada Isolates . Untuk eksekusi asinkron, gunakan async / tunggu, yang Anda kenal dari C #.

Contoh:


Memenuhi permintaan dan mengembalikan hasilnya untuk memperbarui UI:
loadData() async {
  String dataURL = "https://jsonplaceholder.typicode.com/posts";
  http.Response response = await http.get(dataURL);
  setState(() {
    widgets = json.decode(response.body);
  });
}

Ketika respons terhadap permintaan diterima, Anda perlu memanggil metode setState () untuk menggambar ulang pohon widget dengan data baru.

Contoh memuat dan memperbarui data dalam ListView :
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);
    });
  }
}

Pertanyaan:


Bagaimana cara membuat permintaan jaringan?

Menjawab:


Menggunakan plugin http .

Contoh:


Hubungkan ketergantungan melalui pubspec.yaml:
dependencies:
  ...
  http: ^0.11.3+16

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

Pertanyaan:


Bagaimana cara menampilkan progres operasi lama?

Menjawab:


Menggunakan ProgressIndicator .

Perbedaan:


Dalam Xamarin. Bentuk, ini dapat dilakukan secara langsung dengan menempatkan indikator kemajuan di XAML.

Contoh:


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

Struktur dan Sumber Daya Proyek


Pertanyaan:


Di mana menyimpan sumber daya dari berbagai resolusi?

Menjawab:


Dalam assets.

Perbedaan:


Xamarin.Forms tidak memiliki penyimpanan terpadu untuk sumber daya platform, jadi Anda harus menyimpannya di folder platform secara terpisah. Ada Flutter assets. Folder tersebut assetsdapat ditemukan di mana saja di dalam proyek, yang paling penting, tulis path untuk itu dalam file pubspec.yaml.

Informasi tambahan:


Perbandingan ukuran sumber daya grafis di Android dan Flutter.
Kualifikasi kepadatan AndroidRasio piksel bergetar
ldpi0,75x
mdpi1.0x
hdpi1,5x
xhdpi2.0x
xxhdpi3.0x
xxxhdpi4.0x
Contoh tata letak sumber daya:
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

Contoh jalur dalam pubspec.yamlfile:
assets:
 - images/my_icon.jpeg

Contoh menggunakan AssetImage :
return AssetImage("images/a_dot_burr.jpeg");

Contoh penggunaan langsung asset:
@override
Widget build(BuildContext context) {
  return Image.asset("images/my_image.png");
}

Pertanyaan:


Di mana menyimpan string? Bagaimana cara melokalkannya?

Menjawab:


Flutter tidak memiliki tempat khusus untuk menyimpan string saat ini. Mereka diusulkan untuk disimpan sebagai bidang statis di kelas yang terpisah. Plugin digunakan untuk lokalisasi, misalnya flutter_localizations atau l10n .

Perbedaan:


Xamarin.Forms menggunakan file resx.

Contoh:


Penyimpanan:
class Strings {
  static String welcomeMessage = "Welcome To Flutter";
}

Menggunakan:
new Text(Strings.welcomeMessage)

Lokalisasi:
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
  ],
  // ...
)

Pertanyaan:


Di mana file proyek?

Menjawab:


Flutter tidak memiliki file proyek untuk membuka proyek ini di lingkungan pengembangan. File serupa yang paling dekat - pubspec.yaml- berisi dependensi pada plugins dan detail proyek.

Siklus hidup aplikasi


Pertanyaan:


Bagaimana cara menangani acara siklus hidup?

Menjawab:


Menggunakan metode WidgetsBinding dan didChangeAppLifecycleState () .

Informasi tambahan:


Flutter menggunakan FlutterActivity dalam kode Android dan FlutterAppDelegate di iOS, karena ini, mesin Flutter membuat perubahan status pemrosesan sesederhana mungkin. Tetapi jika Anda masih perlu melakukan beberapa pekerjaan tergantung pada negara, maka siklus hidupnya sedikit berbeda:
  • tidak aktif - metode ini hanya di iOS, di Android tidak ada analog;
  • dijeda - mirip dengan onPause () di Android;
  • dilanjutkan - mirip dengan onPostResume () di Android;
  • menangguhkan - mirip dengan onStop di Android, di iOS tidak ada analog.

Lihat dokumentasi AppLifecycleStatus untuk lebih jelasnya .

Contoh:


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

Tata letak


Pertanyaan:


Apa analog dari StackLayout ?

Menjawab:


Analog StackLayout dengan orientasi vertikal adalah Kolom , dan dengan Row - horizontal .

Contoh:


Kolom:
@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'),
    ],
  );
}

Baris:
@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'),
    ],
  );
}

Pertanyaan:


Apa analog dari Grid ?

Menjawab:


GridView .

Contoh:


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

Pertanyaan:


Apa analog dari ScrollView ?

Menjawab:


Analog terdekat adalah SingleChildScrollView . Tapi Flutter paling sering menggunakan ListView untuk membuat konten yang dirayapi .

Contoh:


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

ListView:
@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'),
    ],
  );
}

Penanganan gerakan


Pertanyaan:


Bagaimana cara menangani klik?

Menjawab:


Jika widget mendukung metode ini onPressed, maka Anda dapat menangani klik dengan menggunakannya. Kalau tidak, ini bisa dilakukan melalui GestureDetector .

Contoh:


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

Pertanyaan:


Bagaimana cara menangani gerakan?

Menjawab:


Menggunakan GestureDetector . Mereka dapat menangani tindakan berikut:

Keran



Ketuk dua kali



Tekan lama



Seret vertikal



Seret horizontal



Contoh:


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 dan Adapters


Pertanyaan:


Apa analog dari ListView ?

Menjawab:


ListView .

Perbedaan:


Di Xamarin.Forms, Anda perlu membuat ViewCell dan (paling sering) DataTemplateSelector dan meneruskannya ke ListView . Di Flutter, Anda hanya perlu melewati daftar widget untuk ditampilkan.

Contoh:


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

Pertanyaan:


Bagaimana cara menentukan elemen mana yang diklik?

Menjawab:


Di Flutter, widget elemen harus menangani kliknya sendiri.

Perbedaan:


Xamarin. Bentuk paling umum menggunakan ItemTapped .

Contoh:


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

Pertanyaan:


Bagaimana cara memperbarui ListView secara dinamis ?

Menjawab:


Perbarui daftar data dan panggil setState().

Perbedaan:


Xamarin.Forms menggunakan ItemsSource untuk ini . Di Flutter, setelah setState()widget akan digambar kembali.

Contoh:


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

Informasi tambahan:


Untuk membuat daftar, disarankan untuk menggunakan ListView.Builder .

Contoh:


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

Teks


Pertanyaan:


Bagaimana cara menggunakan font khusus?

Menjawab:


File font yang Anda hanya perlu dimasukkan ke dalam folder (pikirkan nama untuk Anda sendiri) dan tunjukkan path ke sana pubspec.yaml.

Contoh:


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

Pertanyaan:


Bagaimana cara mendesain widget teks?

Menjawab:


Menggunakan parameter:

  • warna;
  • dekorasi;
  • warna dekorasi;
  • dekorasi Gaya;
  • fontFamily;
  • ukuran huruf;
  • gaya tulisan;
  • fontBerat;
  • Kode hash;
  • tinggi;
  • mewarisi;
  • spasi surat;
  • textBaseline;
  • spasi kata.

Pertanyaan:


Apa yang setara dengan Placeholder ?

Menjawab:


The hintText properti dari InputDecoration .

Contoh:


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

Pertanyaan:


Bagaimana cara menunjukkan kesalahan validasi?

Menjawab:


Semua sama dengan InputDecoration dan statusnya.

Contoh:


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

Flutter Plugins


Pertanyaan:


Bagaimana cara mengakses GPS?

Menjawab:


Menggunakan plugin geolocator .

Pertanyaan:


Bagaimana cara mengakses kamera?

Menjawab:


Menggunakan plugin image_picker .

Pertanyaan:


Bagaimana cara masuk melalui Facebook?

Menjawab:


Menggunakan plugin flutter_facebook_login .

Pertanyaan:


Bagaimana cara menggunakan firebase?

Menjawab:


Firebase mendukung plugin Flutter pihak pertama :

Kode khusus platform


Pertanyaan:


Bagaimana cara menentukan platform yang menjalankan kode?

Menjawab:


Menggunakan kelas bidang platformdalam tema atau kelas Platform .

Contoh:


Bidang 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 ';
}

Kelas Platform:
if (Platform.isIOS) {
  return 'iOS';
} else if (Platform.isAndroid) {
  return 'android';
} else if (Platform.isFuchsia) {
  return 'fuchsia';
} else {
  return 'not recognised ';
}

Pertanyaan:


Bagaimana cara memanggil kode platform asli?

Menjawab:


Melalui MethodChannel .

Informasi tambahan:


Lebih detail di sini .

Debugging


Pertanyaan:


Apa alat untuk debugging aplikasi?

Menjawab:


DevTools .

Pertanyaan:


Gimana caranya hot reload?

Menjawab:


Jika aplikasi diluncurkan dari IntelliJ IDE, Android Studio atau VSCode, maka dengan menggabungkan ⌘s/ctrl-satau mengklik ikon hot reload. Jika dimulai dari terminal, maka dengan memasukkan huruf r.

Pertanyaan:


Bagaimana cara mengakses menu pengembang di aplikasi?

Menjawab:


Jika peluncuran berasal dari IDE, maka gunakan alat IDE. Jika dari konsol, gunakan h.

Informasi tambahan:


Daftar lengkap perintah:

BertindakTim dalam terminalFungsi dan Bidang
Hirarki widgetwdebugDumpApp ()
Render pohontdebugDumpRenderTree ()
LayersL.debugDumpLayerTree ()
AksesibilitasS (urutan traversal) atau U (urutan uji hit terbalik)debugDumpSemantics ()
Inspektur widgetsayaWidgetsApp.showWidgetInspectorOverride
Tampilkan garis konstruksihaldebugPaintSizeEnabled
Simulasi berbagai OSHaidefaultTargetPlatform
PerformaPWidgetsApp. showPerformanceOverlay
Tangkapan layar flutter.pngs
Aplikasi ditutupq

Penyimpanan lokal


Pertanyaan:


Bagaimana cara menyimpan key-valuedata dalam aplikasi?

Menjawab:


Menggunakan plugin shared_preferences .

Perbedaan:


Dalam Xamarin Xam.Plugins.Settings. Bentuk digunakan .

Contoh:


Ketergantungan koneksi:
dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^0.4.3

Menggunakan:
SharedPreferences prefs = await SharedPreferences.getInstance();
_counter = prefs.getInt('counter');
prefs.setInt('counter', ++_counter);
setState(() {
  _counter = _counter;
});

Pertanyaan:


Bagaimana cara menyimpan data yang kompleks?

Menjawab:


Menggunakan plugin basis data seperti sqflite atau sarang .

Ini mungkin jawaban untuk pertanyaan dasar. Ini menyimpulkan serangkaian interpretasi. Saya harap mereka bermanfaat bagi semua pengembang yang tertarik dengan kerangka kerja ini. Mungkin Anda bahkan mulai menulis di Flutter dan merekrut Anda ke komunitas ramah pengembang Flutter. Dan saya akan memikirkan artikel baru untuk mengembangkan komunitas dan menjadikan dunia aplikasi tempat yang lebih baik. Semoga Formulir Anda tidak merusak Xamarin!

All Articles