<

プラットフォーム固有の動作と適応

適応哲学

一般に、プラットフォームの適応性には 2 つのケースがあります。

  1. OS環境の挙動に関するもの (テキスト編集やスクロールなど) 異なる動作が発生した場合、それは「間違っている」ことになります。
  2. 従来からアプリに実装されているもの OEM の SDK (iOS での並列タブの使用など) を示すandroid.app.AlertDialogAndroid では)。

この記事では主に自動適応について説明します。 Android および iOS のケース 1 では Flutter によって提供されます。

ケース 2 の場合、Flutter は、 プラットフォーム規約の適切な効果があるが、そうではない アプリのデザインの選択が必要な場合は、自動的に適応します。 議論については、を参照してください。問題 #8410そしてそのマテリアル/Cupertino アダプティブ ウィジェットの問題定義。

さまざまな情報を使用するアプリの例については、 Android と iOS のアーキテクチャ構造を共有 同じコンテンツコードについては、を参照してください。platform_design コードサンプル。

Flutter は Android で見られるナビゲーション パターンを提供します および iOS に対応し、ナビゲーション アニメーションも自動的に適応されます。 現在のプラットフォームに。

の上アンドロイド、 デフォルトNavigator.push()遷移 をモデルにしていますstartActivity()、 通常、これにはボトムアップ アニメーションのバリアントが 1 つあります。

の上iOS:

  • デフォルトNavigator.push()API は iOS からアニメーション化する Show/Push スタイルのトランジション ロケールの RTL 設定に応じて、エンドツースタート。 新ルートの後ろのページも視差スライド iOS と同じ方向です。
  • 次の場合には、別のボトムアップ トランジション スタイルが存在します。 ページルートをプッシュします。PageRoute.fullscreenDialogそれは本当です。これは iOS の Present/Modal スタイルを表します トランジションであり、通常は全画面モーダル ページで使用されます。
An animation of the bottom-up page transition on Android
Androidページ遷移
An animation of the end-start style push page transition on iOS
iOSプッシュ移行
An animation of the bottom-up style present page transition on iOS
iOSの現在の移行

プラットフォーム固有の移行の詳細

の上アンドロイド、 2 つのページ遷移アニメーション スタイルが存在します。 OS のバージョン:

  • API 28 より前では、ボトムアップ アニメーションが使用されます。上にスライドしてフェードインします。
  • API 28 以降では、ボトムアップ アニメーションスライドとクリップで明らかになります。

の上iOSプッシュスタイルトランジションを使用する場合、 Flutter のバンドルCupertinoNavigationBarCupertinoSliverNavigationBarナビゲーションバー 各サブコンポーネントを対応するものに自動的にアニメーション化します。 次または前のページのサブコンポーネントCupertinoNavigationBarまたCupertinoSliverNavigationBar

An animation of the page transition on Android pre-Android P
Android プレ P
An animation of the page transition on Android on Android P
Android ポスト P
An animation of the nav bar transitions during a page transition on iOS
iOS ナビゲーション バー

戻るナビゲーション

の上アンドロイド、 OS の戻るボタンはデフォルトで Flutter に送信されます。 の一番上のルートをポップしますWidgetsAppのナビゲーター。

の上iOS、 エッジ スワイプ ジェスチャを使用して、一番上のルートをポップできます。

A page transition triggered by the Android back button
Androidの戻るボタン
A page transition triggered by an iOS back swipe gesture
iOSのバックスワイプジェスチャ

スクロール

スクロールはプラットフォームの重要な部分です ルック アンド フィール、Flutter が自動的に調整 現在のプラットフォームに一致するスクロール動作。

物理シミュレーション

Android と iOS は両方とも複雑なスクロール物理を備えています 口頭で説明するのが難しいシミュレーション。 一般に、iOS のスクロール可能部分はより重みがあり、 動的摩擦ですが、Android は静摩擦の方が大きいです。 したがって、iOS は徐々に高速化しますが、停止します。 急激ではなくなり、低速では滑りやすくなります。

A soft fling where the iOS scrollable slid longer at lower speed than Android
ソフトフリングの比較
A medium force fling where the Android scrollable reached speed faster and stopped more abruptly after reaching a longer distance
中程度の飛びの比較
A strong fling where the Android scrollable reach speed faster and reached significantly more distance
強力なフリングの比較

オーバースクロール動作

の上アンドロイド、 スクロール可能な領域の端を越えてスクロールすると、オーバースクロールグローインジケーター(色に基づいて 現在のマテリアル テーマの)。

の上iOS、スクロール可能な領域の端を越えてスクロールするオーバースクロール抵抗が増加し、スナップバックします。

Android and iOS scrollables being flung past their edge and exhibiting platform specific overscroll behavior
動的なオーバースクロールの比較
Android and iOS scrollables being overscrolled from a resting position and exhibiting platform specific overscroll behavior
静的オーバースクロールの比較

勢い

の上iOS、 同じ方向に繰り返し投げると勢いが増す そして、連続して飛ばすたびにスピードが上がります。 同等の動作はありませんアンドロイド

Repeated scroll flings building momentum on iOS
iOSのスクロールの勢い

トップに戻る

の上iOS、 OS ステータス バーをタップすると、プライマリがスクロールします コントローラーを一番上の位置までスクロールします。 同等の動作はありませんアンドロイド

Tapping the status bar scrolls the primary scrollable back to the top
iOS ステータス バーをタップしてトップへ

タイポグラフィ

マテリアルパッケージを使用する場合、 タイポグラフィは自動的にデフォルトに設定されます。 プラットフォームに適したフォント ファミリ。 Android では、Roboto フォントが使用されます。 iOS では、OS の San Francisco フォント ファミリが使用されます。

クパチーノ パッケージを使用する場合、デフォルトのテーマ常に San Francisco フォントを使用します。

San Francisco フォント ライセンスでは、その使用が以下に制限されています。 iOS、macOS、または tvOS 上でのみ実行されるソフトウェア。 したがって、Android で実行する場合はフォールバック フォントが使用されます。 プラットフォームが iOS に対してデバッグ オーバーライドされている場合、または デフォルトのクパチーノテーマが使用されます。

マテリアルのテキスト スタイルを適応させることもできます。 iOS のデフォルトのテキスト スタイルに一致するウィジェット。 ウィジェット固有の例は、UIコンポーネントセクション。

Roboto font on Android
Android 上のロボット
San Francisco font on iOS
iOS 上のサンフランシスコ

図像学

マテリアルパッケージを使用する場合、 特定のアイコンは自動的に異なるものを表示します グラフィックスはプラットフォームに依存します。 たとえば、オーバーフロー ボタンの 3 つのドット iOS では水平方向、Android では垂直方向になります。 iOS では戻るボタンは単純な山形ですが、 Android にはステム/シャフトがあります。

Android appropriate icons
Android のアイコン
iOS appropriate icons
iOSのアイコン

マテリアル ライブラリには、プラットフォームに適応したアイコンのセットも提供されます。Icons.adaptive

触覚フィードバック

マテリアル パッケージとクパチーノ パッケージは自動的に作成されます プラットフォームに適切な触覚フィードバックをトリガーします 特定のシナリオ。

例えば、 テキストフィールドを長押しして単語を選択すると「バズ」がトリガーされます Android では振動しますが、iOS では振動しません。

iOS でピッカー項目をスクロールすると、 Android では「軽い衝撃」でノックがあり、フィードバックがありません。

テキスト編集

Flutter は編集中に以下の適応も行います。 テキストフィールドの内容を現在のプラットフォームに合わせます。

キーボードジェスチャーによるナビゲーション

の上アンドロイド、 ソフトキーボードのスペースバーで水平スワイプが可能 をクリックして、マテリアルおよびクパチーノのテキストフィールドでカーソルを移動します。

の上iOS3D Touch 機能を備えたデバイス、 ソフト上で力を加えて押してドラッグするジェスチャを実行できます。 キーボードを使用して、フローティング カーソルを介して 2D でカーソルを移動します。 これは、マテリアル テキスト フィールドとクパチーノ テキスト フィールドの両方で機能します。

Moving the cursor via the space key on Android
Androidのスペースキーカーソル移動
Moving the cursor via 3D Touch drag on the keyboard on iOS
iOS 3Dタッチドラッグカーソル移動

テキスト選択ツールバー

Android 上のマテリアル、 Android スタイル選択ツールバーは次の場合に表示されます。 テキストフィールドでテキストが選択されます。

iOS 上のマテリアルまたは使用時クパチーノ、 iOS スタイル選択ツールバーは、テキストが選択されているときに表示されます。 選択はテキストフィールドで行われます。

Android appropriate text toolbar
Android のテキスト選択ツールバー
iOS appropriate text toolbar
iOS テキスト選択ツールバー

シングルタップジェスチャ

Android 上のマテリアル、 テキストフィールドを 1 回タップすると、カーソルが 蛇口の位置。

折りたたまれたテキスト選択にも、ドラッグ可能なテキストが表示されます。 ハンドルを使用してカーソルを移動します。

iOS 上のマテリアルまたは使用時クパチーノ、 テキストフィールドを 1 回タップすると、カーソルが タップされた単語の最も近い端。

iOS では、折りたたまれたテキスト選択にはドラッグ可能なハンドルがありません。

Moving the cursor to the tapped position on Android
アンドロイドタップ
Moving the cursor to the nearest edge of the tapped word on iOS
iOSタップ

長押しジェスチャ

Android 上のマテリアル、 長押しすると、長押しした単語が選択されます。 選択ツールバーはリリース時に表示されます。

iOS 上のマテリアルまたは使用時クパチーノ、 長押しすると、カーソルが 長押し。選択ツールバーはリリース時に表示されます。

Selecting a word via long press on Android
Android 長押し
Selecting a position via long press on iOS
iOS 長押し

長押しドラッグジェスチャ

Android 上のマテリアル、 長押ししたままドラッグすると、選択した単語が展開されます。

iOS 上のマテリアルまたは使用時クパチーノ、 長押ししたままドラッグするとカーソルが移動します。

Expanding word selection via long press drag on Android
Android 長押しドラッグ
Moving the cursor via long press drag on iOS
iOS 長押しドラッグ

ダブルタップジェスチャ

Android と iOS の両方で、 ダブルタップすると、メッセージを受信する単語が選択されます。 ダブルタップすると選択ツールバーが表示されます。

Selecting a word via double tap on Android
Android ダブルタップ
Selecting a word via double tap on iOS
iOS ダブルタップ

UIコンポーネント

このセクションには、適応方法に関する予備的な推奨事項が含まれています。 iOS 上で自然で魅力的なエクスペリエンスを提供するマテリアル ウィジェット。 あなたのフィードバックは大歓迎です問題 #8427。

.adaptive() コンストラクターを備えたウィジェット

いくつかのウィジェットのサポート.adaptive()コンストラクター。 次の表に、これらのウィジェットを示します。 アダプティブ コンストラクターは、対応する Cupertino コンポーネントを置き換えます。 アプリが iOS デバイス上で実行されるとき。

次の表のウィジェットは主に入力に使用されます。 を選択し、システム情報を表示します。 これらのコントロールはオペレーティング システムと緊密に統合されているため、 ユーザーはそれらを認識して応答するように訓練されています。 したがって、プラットフォームの規則に従うことをお勧めします。

マテリアルウィジェット クパチーノ ウィジェット アダプティブ コンストラクター
Switch in Material 3
Switch
Switch in HIG
CupertinoSwitch
Switch.adaptive()
Slider in Material 3
Slider
Slider in HIG
CupertinoSlider
Slider.adaptive()
Circular progress indicator in Material 3
CircularProgressIndicator
Activity indicator in HIG
CupertinoActivityIndicator
CircularProgressIndicator.adaptive()
 Checkbox in Material 3
Checkbox
Checkbox in HIG
CupertinoCheckbox
Checkbox.adaptive()
Radio in Material 3
Radio
Radio in HIG
CupertinoRadio
Radio.adaptive()

トップアプリバーとナビゲーションバー

Android 12以降、トップアプリのデフォルトUI バーは、で定義された設計ガイドラインに従っています。資料3。 iOS では、「ナビゲーション バー」と呼ばれる同等のコンポーネント で定義されていますApple のヒューマン インターフェイス ガイドライン(HIG)。

 Top App Bar in Material 3
マテリアル 3 のトップ アプリ バー
Navigation Bar in Human Interface Guidelines
ヒューマン インターフェイス ガイドラインのナビゲーション バー

Flutter アプリのアプリバーの特定のプロパティを調整する必要があります。 システムアイコンやページ遷移など。 これらは使用時にすでに自動的に適応されています。 素材AppBarSliverAppBarウィジェット。 これらのウィジェットのプロパティをさらにカスタマイズして、より良いものにすることもできます。 以下に示すように、iOS プラットフォームのスタイルと一致します。

// Map the text theme to iOS styles
TextTheme cupertinoTextTheme = TextTheme(
    headlineMedium: CupertinoThemeData()
        .textTheme
        .navLargeTitleTextStyle
         // fixes a small bug with spacing
        .copyWith(letterSpacing: -1.5),
    titleLarge: CupertinoThemeData().textTheme.navTitleTextStyle)
...

// Use iOS text theme on iOS devices
ThemeData(
      textTheme: Platform.isIOS ? cupertinoTextTheme : null,
      ...
)
...

// Modify AppBar properties
AppBar(
        surfaceTintColor: Platform.isIOS ? Colors.transparent : null,
        shadowColor: Platform.isIOS ? CupertinoColors.darkBackgroundGray : null,
        scrolledUnderElevation: Platform.isIOS ? .1 : null,
        toolbarHeight: Platform.isIOS ? 44 : null,
        ...
      ),

ただし、アプリバーが並んで表示されるため、 ページ内の他のコンテンツの場合は、スタイルを調整することのみをお勧めします アプリケーションの残りの部分と一貫性がある限り。ご覧いただけます 追加のコードサンプルと詳細な説明は、アプリバーの適応に関する GitHub ディスカッション。

下部のナビゲーション バー

Android 12 以降、下部ナビゲーションのデフォルト UI バーは、で定義された設計ガイドラインに従っています。資料3。 iOS では、「タブ バー」と呼ばれる同等のコンポーネント で定義されていますApple のヒューマン インターフェイス ガイドライン(HIG)。

Bottom Navigation Bar in Material 3
マテリアル 3 の下部ナビゲーション バー
Tab Bar in Human Interface Guidelines
ヒューマンインターフェイスガイドラインのタブバー

タブ バーはアプリ全体で永続的であるため、タブ バーはアプリと一致する必要があります。 独自のブランディング。ただし、マテリアルのデフォルトを使用することを選択した場合は、 Android でスタイルを設定する場合は、デフォルトの iOS に適応することを検討してください。 タブバー。

プラットフォーム固有の下部ナビゲーション バーを実装するには、 Flutterを使用できますNavigationBarAndroid のウィジェット そしてそのCupertinoTabBariOS のウィジェット。 以下はできるコードスニペットです プラットフォーム固有のナビゲーション バーを表示するように調整します。

final Map<String, Icon> _navigationItems = {
    'Menu': Platform.isIOS ? Icon(CupertinoIcons.house_fill) : Icon(Icons.home),
    'Order': Icon(Icons.adaptive.share),
  };

...

Scaffold(
  body: _currentWidget,
  bottomNavigationBar: Platform.isIOS
          ? CupertinoTabBar(
              currentIndex: _currentIndex,
              onTap: (index) {
                setState(() => _currentIndex = index);
                _loadScreen();
              },
              items: _navigationItems.entries
                  .map<BottomNavigationBarItem>(
                      (entry) => BottomNavigationBarItem(
                            icon: entry.value,
                            label: entry.key,
                          ))
                  .toList(),
            )
          : NavigationBar(
              selectedIndex: _currentIndex,
              onDestinationSelected: (index) {
                setState(() => _currentIndex = index);
                _loadScreen();
              },
              destinations: _navigationItems.entries
                  .map<Widget>((entry) => NavigationDestination(
                        icon: entry.value,
                        label: entry.key,
                      ))
                  .toList(),
            ));

テキストフィールド

Android 12以降、テキストフィールドのデフォルトUIはデザインに従います で定義されたガイドライン資料3(M3)。 iOS では、Apple のヒューマンインターフェースガイドライン(HIG) 定義 同等のコンポーネント。

Text Field in Material 3
資料 3 のテキストフィールド
Text Field in Human Interface Guidelines
HIG のテキスト フィールド

テキストフィールドにはユーザー入力が必要なので、
設計はプラットフォームの規約に従う必要があります。

プラットフォーム固有の機能を実装するには1321038f-72ac-42a4-9fe3-b97668157bc​​7Flutter では、スタイルを調整できます。 材料TextField

Widget _createAdaptiveTextField() {
  final _border = OutlineInputBorder(
    borderSide: BorderSide(color: CupertinoColors.lightBackgroundGray),
  );

  final iOSDecoration = InputDecoration(
    border: _border,
    enabledBorder: _border,
    focusedBorder: _border,
    filled: true,
    fillColor: CupertinoColors.white,
    hoverColor: CupertinoColors.white,
    contentPadding: EdgeInsets.fromLTRB(10, 0, 0, 0),
  );

  return Platform.isIOS
      ? SizedBox(
          height: 36.0,
          child: TextField(
            decoration: iOSDecoration,
          ),
        )
      : TextField();
}

テキストフィールドの適応について詳しくは、以下をご覧ください。テキストフィールドに関する GitHub ディスカッション。 ディスカッションでフィードバックを残したり、質問したりできます。

アラートダイアログ

Android 12 以降、アラート ダイアログのデフォルト UI (「基本ダイアログ」とも呼ばれます) は設計ガイドラインに従います で定義されています資料3(M3)。 iOS では、「アラート」と呼ばれる同等のコンポーネントが Apple のヒューマンインターフェースガイドライン(HIG)。

Basic Dialog in Material 3
M3 の基本ダイアログ
Alert in Human Interface Guidelines
HIG でのアラート

多くの場合、アラート ダイアログはオペレーティング システムと緊密に統合されているため、 通常、その設計はプラットフォームの規約に従う必要があります。 これは、ダイアログを使用してユーザー入力を要求する場合に特に重要です。 セキュリティ、プライバシー、および破壊的な操作 (ファイルの削除など) について 永久的に)。例外として、ブランドのアラート ダイアログ デザインは次の場合に使用できます。 重要ではないユーザー フローを使用して、特定の情報やメッセージを強調表示します。

プラットフォーム固有のアラート ダイアログを実装するには、 Flutterを使用できますAlertDialogAndroid のウィジェット そしてそのCupertinoAlertDialogiOS のウィジェット。以下はできるコードスニペットです プラットフォーム固有の警告ダイアログを表示するように調整します。

void _showAdaptiveDialog(
  context, {
  required Text title,
  required Text content,
  required List<Widget> actions,
}) {
  Platform.isIOS || Platform.isMacOS
      ? showCupertinoDialog<String>(
          context: context,
          builder: (BuildContext context) => CupertinoAlertDialog(
            title: title,
            content: content,
            actions: actions,
          ),
        )
      : showDialog(
          context: context,
          builder: (BuildContext context) => AlertDialog(
            title: title,
            content: content,
            actions: actions,
          ),
        );
}

アラート ダイアログの適応について詳しくは、以下をご覧ください。ダイアログの適応に関する GitHub ディスカッション。 ディスカッションでフィードバックを残したり、質問したりできます。

9f9a859​​5-b33f-459f-b0a2-ac4896ae2619