Halo, Habr! Saya mempersembahkan kepada Anda terjemahan artikel
“Apakah aplikasi Flutter memimpikan widget yang sadar platform?”
Ketika mengembangkan aplikasi di Flutter dengan desain asli untuk iOS dan Android, saya menemukan fakta bahwa saya harus menulis banyak persyaratan untuk memeriksa platform tempat kode dijalankan, sambil membuat dua implementasi UI yang serupa. Saya tidak suka ini dan saya senang saya menemukan sebuah artikel yang membantu saya memecahkan masalah saya.
Tentang Penulis: Swav Kulinski - Pengembang Android Utama di The App Business, Flutter GDE.
Selanjutnya, kita akan berbicara atas nama penulis.
Flutter adalah solusi pengembangan aplikasi mobile lintas platform yang menjanjikan kebebasan mutlak dalam menciptakan antarmuka pengguna tanpa memandang platform. Ini dicapai oleh fakta bahwa kerangka kerja menggunakan mesin rendering sendiri untuk menarik widget.
Masalah dengan banyak solusi lintas-platform adalah bahwa mereka terlihat sama di iPhone dan Android. Tetapi bagaimana dengan perusahaan yang perlu mempertahankan tampilan platform? Siapa yang perlu menggunakan Desain Material untuk Android dan Antarmuka Manusia untuk iOS? Untuk perusahaan seperti itu Flutter cocok, dilengkapi dengan paket yang berisi satu set widget khusus untuk iOS dan Android, yang disebut Cupertino dan Material.

Flutter adalah cross-platform di alam, tetapi ketika datang ke tata letak UI, yang seharusnya terlihat asli untuk setiap platform, ini tidak sepenuhnya benar. Kita harus melakukan dua implementasi tata letak yang serupa. Ini disebabkan oleh fakta bahwa, misalnya, untuk iOS, CupertinoNavigationBar harus di CupertinoPageScaffold, dan di Android, AppBar di dalam Scaffold. Fitur ini mengurangi keuntungan cross-platform di Flutter, karena untuk setiap platform Anda harus menulis kode sendiri untuk tata letak.
Saya ingin mengusulkan pendekatan yang memungkinkan Anda untuk membuat antarmuka abstrak dan menyesuaikan tampilan dan perilaku aplikasi tergantung pada platform mana ia berjalan.
Pertimbangkan konstruktor berikut untuk dua widget yang menyediakan bilah aplikasi teratas:
CupertinoNavigationBar ({ this.leading, this.middle, })
dan
AppBar ({ this.leading, this.title })
Kedua widget di atas memainkan peran yang sama, menjadi panel teratas dalam aplikasi dengan gaya Cupertino dan Material. Tapi tetap saja mereka membutuhkan input dengan cara yang berbeda. Diperlukan solusi yang akan abstrak dari cara kami membuat widget tertentu, dan pada saat yang sama memberikan implementasi tergantung pada platform. Kami akan menggunakan metode pabrik lama yang baik.
import 'package:flutter/material.dart'; import 'dart:io' show Platform; abstract class PlatformWidget<I extends Widget, A extends Widget> extends StatelessWidget { @override Widget build(BuildContext context) { if (Platform.isAndroid) { return createAndroidWidget(context); } else if (Platform.isIOS) { return createIosWidget(context); } // platform not supported returns an empty widget return Container(); } I createIosWidget(BuildContext context); A createAndroidWidget(BuildContext context); }
Bahkan, kelas di atas adalah pabrik widget yang bergantung pada platform yang, ketika diimplementasikan, dapat menyediakan konstruktor khusus (atau beberapa konstruktor bernama) yang mendukung kebutuhan kedua kelas tertentu.
Saya memilih obat generik untuk mengembalikan kelas tertentu, karena terkadang widget induk memerlukan jenis tertentu, yang harus dikembalikan dari widget anak.
Sekarang kita bisa menerapkan widget pertama kita.
class PlatformAppBar extends PlatformWidget<CupertinoNavigationBar, AppBar> { final Widget leading; final Widget title; PlatformAppBar({ this.leading, this.title, }); @override AppBar createAndroidWidget(BuildContext context) { return AppBar( leading: leading, title: title, ); } @override CupertinoNavigationBar createIosWidget(BuildContext context) { return CupertinoNavigationBar( leading: leading, middle: title, ); } }
Cukup sederhana, bukan? Harap perhatikan bahwa kami memiliki kontrol penuh atas konten widget di panel aplikasi.
Misalkan kita menerapkan Scaffold dan Button.
class PlatformScaffoldWidget extends PlatformWidget<CupertinoPageScaffold,Scaffold> { ... } class PlatformButton extends PlatformWidget<CupertinoButton,FlatButton> { ... }
Sekarang kita siap untuk menggunakan dan menggunakan kembali widget berorientasi platform kita.
Widget build(BuildContext context) { return PlatformScaffoldWidget( appBar: PlatformAppBarWidget( leading: PlatformButton( child: Icon(Icons.ic_arrow_back), onClick: () => _handleBack() ), title: Text("I love my Platform"), ), content: ... ); }
Selesai! Kode di atas akan menampilkan bilah aplikasi berorientasi platform di kedua platform, dan PlatformScaffoldWidget kami siap digunakan kembali di seluruh aplikasi tanpa masalah.
Kode dapat dilihat di
github.