モバイルアプリのインターフェース開発は、UIコンポーネントとフレームワークの理解から始まります。この記事では、Material Design、Human Interface Guidelines、SwiftUI、Jetpack Compose、Flutter Widgets、測定単位(dp、sp、pt、px)、およびNavigationViewやRecyclerViewからSafe AreaやDark Modeまでの主要なUI要素について説明します。この資料は、理論から最初のプロジェクトに移行する初心者向けです。詳細については、公式Material Designドキュメントを参照してください。
重要ポイント
各プラットフォームは独自のルールとコンポーネントのセットを提供します。Androidの場合、それは2014年にGoogleが開発したMaterial Designです。Material Designは物理的な素材のメタファーを使用します — レイヤー、シャドウ(Elevation)、アニメーション遷移、アダプティブレイアウト。主要な原則には、Elevationによる階層、意味のある動き、さまざまなフォームファクターへの適応性が含まれます。Material Design 3(Material You) — ダイナミックテーマとパーソナライズされたカラーを備えた最新バージョン — を探索することをお勧めします。
AppleはHuman Interface Guidelines(HIG)を提供しています — iOS、iPadOS、macOS、watchOS、tvOS向けのルールセットです。HIGは、明確なタイポグラフィ(San Francisco)、NotchとDynamic Islandを考慮するSafe Area、ジェスチャーベースのナビゲーション、一貫性を重視しています。Material Designとは異なり、HIGは「レイヤー」やElevationを使用しません — 代わりに、ブラー(vibrancy)、シャドウ、繊細な区切り線を使用します。完全なHIGドキュメントは、新しいiOSリリースに合わせて定期的に更新されます。
IT Sectrでは、クライアントのプラットフォームに応じて両方のデザインシステムを使用しています。クロスプラットフォームのFlutterプロジェクトでは、Material DesignとHIGのベストプラクティスを組み合わせた統一デザインシステムを開発しています。このアプローチにより、コードの重複なしに各プラットフォームでネイティブなUXを維持できます。
UIを構築する従来のアプローチは、XML(Android)またはInterface Builder/コード(iOS)を介した命令型レイアウトです。最新の代替手段は宣言型フレームワークで、開発者が各状態でのインターフェースの外観を記述し、フレームワークが更新を処理します。
Jetpack Composeは、KotlinでネイティブUIを構築するためのGoogleの最新ツールキットです。XMLレイアウトの代わりに、Kotlinのコンポーザブル関数(@Composable)が使用されます。Composeは完全に宣言型です:データが変更されると、画面の変更された部分のみが再描画されます。テキストとボタンを備えたシンプルな画面の例:
@Composable
fun GreetingScreen() {
var count = remember { mutableStateOf(0) }
Column {
Text(text = "Нажато: $count")
Button(onClick = { count++ }) {
Text("Нажми меня")
}
}
}
SwiftUIは、2019年に発表されたAppleの宣言型フレームワークです。統一されたAPIを通じて、すべてのAppleプラットフォーム(iOS、iPadOS、macOS、watchOS、tvOS)で動作します。SwiftUIは、データ管理にView構造体、@Stateおよび@Bindingプロパティ、スタイリングにモディファイアを使用します。SwiftUIでの上記の例の相当品:
struct GreetingView: View {
@State private var count = 0
var body: some View {
VStack {
Text("Нажато: \(count)")
Button("Нажми меня") {
count += 1
}
}
}
}
GoogleのFlutterは、独自のウィジェットライブラリを使用します。Flutterではすべてがウィジェットです — パディングから画面全体まで。ウィジェットは、StatelessWidget(不変)とStatefulWidget(状態を持つ)に分類されます。基本的なコンテナはContainer、Row、Column、Stackです。Flutterはプラットフォームのネイティブコンポーネントを使用しません — Skia Engineを介してすべてを描画し、AndroidとiOSの両方で一貫した外観を保証します。
class GreetingWidget extends StatefulWidget {
@override
State createState() => _GreetingWidgetState();
}
class _GreetingWidgetState extends State<GreetingWidget> {
int count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Нажато: $count'),
ElevatedButton(
onPressed: () => setState(() => count++),
child: Text('Нажми меня'),
),
],
);
}
}
宣言型フレームワークの普及にもかかわらず、レガシープロジェクトのサポートと深いカスタマイズのために、ネイティブコンポーネントの理解は重要です。
AndroidのナビゲーションはActivity(画面アクティビティ)とFragment(1つのActivity内のフラグメント)に基づいています。Jetpack Navigation Componentは、ナビゲーショングラフを介して画面間の遷移を簡素化します。iOSでは、ナビゲーションはNavigationController — アニメーション遷移を持つコントローラーのスタック — を介して実装されます。Tab BarとBottom Navigationは、アプリの主要セクション間の切り替えを可能にします。Drawer(サイドメニュー)とToolbar/ActionBarは、追加のアクションに使用されます。Android Navigation Componentは、すべての新規プロジェクトで推奨されています。
大量のデータを表示するために、AndroidはRecyclerView — ViewHolderの再利用を備えた効率的なコンテナ — を使用します。iOSでの同等品はUITableView(垂直リスト)とUICollectionView(グリッド)です。Jetpack ComposeはLazyColumnとLazyVerticalGridを提供し、SwiftUIはListとLazyVStack/LazyHStackを提供します。Lazyコンポーネントの主な利点は、表示されている要素のみをレンダリングすることです。
| プラットフォーム | リストコンポーネント | グリッドコンポーネント | 遅延読み込み |
|---|---|---|---|
| Android (View System) | RecyclerView + ListView | RecyclerView GridLayoutManager | はい |
| Android (Compose) | LazyColumn | LazyVerticalGrid | はい |
| iOS (UIKit) | UITableView | UICollectionView | はい |
| iOS (SwiftUI) | List / LazyVStack | LazyVGrid | はい |
| Flutter | ListView.builder | GridView.builder | はい |
Android View Systemは、いくつかのレイアウトコンテナを提供します:ConstraintLayout(柔軟な制約システム)、LinearLayout(線形配置)、RelativeLayout(相対配置)、FrameLayout(レイヤースタッキング)。iOSでは、Core Auto Layoutは制約システム(NSLayoutConstraint)を使用して要素の配置を記述します。SwiftUIとFlutterは、それぞれVStack/HStack/ZStackとRow/Column/Stackを使用します。
モバイルデバイスのUIコンポーネントは、異なるピクセル密度を考慮して表示されます。すべての画面でインターフェースを同じように見せるために、密度非依存単位が使用されます。
| 単位 | プラットフォーム | 説明 |
|---|---|---|
| dp | Android | 密度非依存ピクセル — mdpi画面で1pxに相当する抽象単位 |
| sp | Android | スケール非依存ピクセル — フォント用、ユーザーのフォントサイズ設定を尊重 |
| pt | iOS | ポイント — タイポグラフィ単位、1x(非Retina)画面で1pt = 1px |
| px | すべて | 物理的な画面ピクセル — 密度が異なるためレイアウトには非推奨 |
画面密度は次のように分類されます:mdpi(160 dpi、1x)、hdpi(240 dpi、1.5x)、xhdpi(320 dpi、2x)、xxhdpi(480 dpi、3x)、xxxhdpi(640 dpi、4x)。画像を準備する際は、すべての密度のリソースを作成する必要があります:icon.png、icon_hdpi.png、icon_xhdpi.pngなど。ベクター形式(AndroidのVectorDrawable、iOSのSF Symbols)は、複数のラスターリソースの問題を解決します。
IT Sectrでは、Figmaからアイコンをエクスポートするためにスケーリング係数を使用しています:iOS用に1x、2x、3x、Android用にmdpi、hdpi、xhdpi、xxhdpi、xxxhdpiでエクスポートします。これにより、タブレットや折りたたみスマートフォンを含むすべてのデバイスでシャープな表示が保証されます。
最新のモバイルアプリUIコンポーネントは、いくつかの標準をサポートする必要があります。これらがないとユーザーエクスペリエンスは不完全になります。
ダークモードは、最新のアプリケーションでは必須のオプションです。Material Design 3とiOS 13+は、ダークテーマの組み込みサポートを提供しています。色を反転させるのではなく、個別のカラーパレット(暗い背景、明るいテキスト、二次要素の低コントラスト)を使用することが重要です。自動切り替えはデバイスのシステムテーマに連動させることができます。
最新のiPhoneにはNotch(フロントカメラの切り欠き)とDynamic Islandがあります。Androidデバイスにも切り欠きと丸みを帯びた角(Corner Radius)があります。Safe Areaは、システム要素(ステータスバー、ホームインジケーター)、ナビゲーションバー、切り欠きがないことが保証された画面領域です。iOSはSafe Area Insetsを自動的に適用します。Androidでは、WindowInsetsまたはDisplayCutoutを介した明示的なチェックが必要です。
アクセシビリティは、障害を持つ人々がアプリを利用できるようにします。主な要件:TalkBack(Android)とVoiceOver(iOS)のサポート、ImageViewの適切なcontentDescription、十分な色のコントラスト(テキストは最低4.5:1)、フォントスケーリングのためのDynamic Type(iOS)サポート、視覚なしのナビゲーション、ジェスチャーの代替手段。WCAG 2.1は国際的なアクセシビリティ標準です。
国際化(i18n)は、複数の言語と地域形式をサポートするためのアプリの準備です。ローカライゼーション(l10n)は、文字列、日付、通貨、文化的特性の翻訳です。Androidはリソースディレクトリ(values-ru、values-de)を使用し、iOSはLocalizable.stringsとXLIFFを使用します。FlutterはARB翻訳ファイルでflutter_localizationsをサポートしています。
タッチインタラクションには多くのジェスチャーが含まれます:タップ、ロングプレス、スワイプ、ピンチズーム、プル・トゥ・リフレッシュ、ドラッグ&ドロップ。AndroidはGestureDetector、iOSはUIGestureRecognizerを使用します。iOSは、Taptic Engineを介した触覚フィードバックを備えた3D Touch(Force Touch)とHaptic Touchもサポートしています。
よくある質問
Material Design(Google)は、シャドウ、レイヤー、アニメーション遷移を備えた「マテリアル」メタファーを使用しますが、HIG(Apple)は明確さ、Safe Area、Dynamic Typeに依存しています。Material DesignはAndroidに、HIGはiOSに推奨されています。デザインシステムの選択はナビゲーションにも影響します:AndroidはBottom NavigationとNavigation Drawerを好み、iOSはTab BarとNavigation Controllerを好みます。
Jetpack ComposeはAndroid用の宣言型フレームワーク、SwiftUIはiOS用です。どちらも宣言型アプローチを使用し、UI開発を簡素化します。ComposeはKotlinとAndroid Architecture Componentsとより密接に統合され、SwiftUIはCombineとAppleエコシステム全体と統合されています。
レスポンシブデザインは、インターフェースが画面サイズ、向き、ピクセル密度に適応するアプローチです。相対単位(dp、sp、pt)、Auto Layout、またはConstraintLayoutが使用されます。タブレット、折りたたみデバイス、デスクトップウィンドウ(iPad Stage Manager)には、追加の適応(Split View、マスター詳細レイアウト)が必要です。
Androidではdp(密度非依存ピクセル)とsp(スケール非依存ピクセル)、iOSではpt(ポイント)。pxはハードウェアピクセルです。dpとptは、異なる画面密度(mdpi(1x)、hdpi(1.5x)、xhdpi(2x)、xxhdpi(3x)、xxxhdpi(4x))で同じ物理サイズを提供します。
アクセシビリティは、障害を持つ人々がインターフェースを使用できるようにします:スクリーンリーダーのサポート、大きなテキスト、コントラスト。a11yがないと、アプリはApp StoreやGoogle Playでの公開が承認されません。さらに、アクセシビリティはすべてのユーザーのUXを向上させます — たとえば、Dynamic Typeのサポートは弱視の人々を助けます。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。