Flutterアプリはプラットフォームベースのウィジェットを夢見ていますか?

こんにちは、Habr! 「フラッターアプリはプラットフォーム対応ウィジェットを夢見ていますか?」という記事の翻訳を紹介します。



iOSとAndroidのネイティブデザインを使用してFlutterでアプリケーションを開発するとき、2つの同様のUI実装を行いながら、コードが実行されるプラットフォームをチェックするための一連の条件を記述する必要があるという事実に直面しました。 気に入らなかったので、問題の解決に役立つ記事に出会えてうれしいです。



著者について:Swav Kulinski-アプリビジネスのリードAndroidデベロッパー、Flutter GDE。

次に、著者に代わって話をします。



Flutterは、プラットフォームに関係なくユーザーインターフェイスを作成する際の絶対的な自由を約束するクロスプラットフォームモバイルアプリケーション開発ソリューションです。 これは、フレームワークが独自のレンダリングエンジンを使用してウィジェットを描画するという事実によって実現されます。



多くのクロスプラットフォームソリューションの問題は、iPhoneとAndroidで同じように見えることです。 しかし、プラットフォームの外観を維持する必要がある企業はどうでしょうか? AndroidのMaterial DesignとiOSのHuman Interfaceを使用する必要があるのは誰ですか? そのような企業には、Flutterが適切であり、iOSおよびAndroid用のCupertinoおよびMaterialと呼ばれるカスタムウィジェットのセットを含むパッケージが装備されています。







Flutterは本質的にクロスプラットフォームですが、各プラットフォームにネイティブに見えるレイアウトUIに関しては、これは完全に真実ではありません。 同様のレイアウトを2つ実装する必要があります。 これは、たとえば、iOSの場合はCupertinoNavigationBarがCupertinoPageScaffoldに、Androidの場合はScaffold内のAppBarにある必要があるという事実によるものです。 プラットフォームごとにレイアウト用の独自のコードを記述する必要があるため、この機能はFlutterのクロスプラットフォームの利点を減らします。



抽象インターフェイスを作成し、実行するプラットフォームに応じてアプリケーションの外観と動作を調整できるアプローチを提案したいと思います。



トップアプリケーションバーを提供する2つのウィジェットの次のコンストラクターを検討してください。



CupertinoNavigationBar ({ this.leading, this.middle, })
      
      





そして



  AppBar ({ this.leading, this.title })
      
      





上記のウィジェットは両方とも同じ役割を果たし、CupertinoとMaterialのスタイルのアプリケーションのトップパネルです。 しかし、それでも別の方法で入力が必要です。 特定のウィジェットを作成する方法から抽象化し、同時にプラットフォームに応じた実装を保証するソリューションが必要です。 古き良きファクトリーメソッドを使用します。



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





実際、上記のクラスはプラットフォームに依存するウィジェットファクトリであり、実装されると、両方の特定のクラスのニーズをサポートするカスタムコンストラクター(またはいくつかの名前付きコンストラクター)を提供できます。



特定のクラスを返すためにジェネリックを選択しました。親ウィジェットには特定のタイプが必要な場合があり、それは子ウィジェットから返す必要があるためです。



これで、最初のウィジェットを実装できます。



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





かなり簡単ですね。 アプリケーションパネルのウィジェットのコンテンツを完全に制御できることに注意してください。



ScaffoldとButtonを実装したとします。



 class PlatformScaffoldWidget extends PlatformWidget<CupertinoPageScaffold,Scaffold> { ... } class PlatformButton extends PlatformWidget<CupertinoButton,FlatButton> { ... }
      
      





これで、プラットフォーム指向のウィジェットを使用して再利用する準備が整いました。



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





できた! 上記のコードは両方のプラットフォームでプラットフォーム指向のアプリケーションバーを表示し、PlatformScaffoldWidgetは問題なくアプリケーションの残りの部分で再利用する準備ができています。



コードはgithubで表示できます



All Articles