search
LoginSignup
9
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

FlutterのWidgetでOS判定を行う場合に dart:io.Platform を使うべきではない

FlutterでOS判定をする際、多くの記事で Platform.isIOS Platform.isAndroid を用いて解説されていますが、これは誤りを含んでいるように思います。
ThemeData#platform のドキュメントにはこう書かれています。

Widgets from the material library should use this getter (via Theme.of) to determine the current platform for the purpose of emulating the platform behavior (e.g. scrolling or haptic effects). (中略) The dart.io.Platform object should only be used directly when it's critical to actually know the current platform, without any overrides possible (for example, when a system API is about to be called).

(訳) マテリアルライブラリのウィジェットは、プラットフォームの挙動(スクロールや触覚効果など)をエミュレートする目的で現在のプラットフォームを決定するのにTheme.ofを介してこのゲッター(訳注: platform のこと)を使用すべきです。(中略) dart:io.Platformオブジェクトは現在のプラットフォームを実際に知ることが重要で、上書きができない場合(例えばシステムAPIを呼び出そうとしている場合)にのみ直接使用すべきです。

つまり、Widgetの見た目を出し分ける目的では Platform.is* は使用するのは好ましくないということです。

このように書かれているのは、Flutterには見た目を上書きできる機能がありますが、OSの挙動にまつわる処理まで変更されてしまうことがないように dart:io.Platform の値は変わることがないからです。

代わりにWidgetでは、 Theme.of(context).platform で比較をすべきです。

Theme.of(context).platform == TargetPlatform.android
Theme.of(context).platform == TargetPlatform.iOS

こうすることにより、例えばAndroidの実機やエミュレータでデバッグしている状況でiOSのウィジェットの挙動も見たいときに、themeに1行追加するだけで確認できます。

MaterialApp(
  theme: ThemeData(
    platform: TargetPlatform.iOS,
    ...
  ),
  ...
)

(ちなみにDart DevToolsにPlatformをオーバーライドする機能もありますが、私の環境では動きませんでした)

もちろんシステムAPIを呼び出す部分はAndroidのままのため、実際に動くかiOS端末で確認する必要はありますが、iOSのビルドは比較的遅いため、ウィジェットの見た目のチェックでは役に立つかと思います。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
9
Help us understand the problem. What are the problem?