画面ビュー WebView

前回の授業では画面UIの配置場所を学びました。今回は引き続き解説します。

単一ネイティブWebビュー(WebView)を理解する

NativePHPで開発されたすべてのモバイルアプリは、単一ネイティブWebビュー(WebView)を中核として動作します。WebViewを利用することで、普段慣れているフロントエンドWeb技術でアプリ画面(UI)を作成可能です。内部にブラウザエンジンを内蔵しているため、Webページをレンダリングできる仕組みです。

WebViewは既定で画面全体を占有します。カメラ起動などの機能を開くと、一時的にカメラ画面に上書きされます。

NativePHPの仕組み:PHPバックエンド + 任意のフロントエンドスタック(Vue、jQuery、Tailwindなど)によるハイブリッド開発

WebViewは常に最前面に表示され、カメラ・内蔵ブラウザなどフルスクリーン処理のときだけ隠れます。アプリで表示するUI画面はすべてこのWebViewが担います。

NativePHPモバイル版の根本構造:単一WebViewコンテナ。ネイティブな複数ページ階層は存在しません。つまりNativePHPは画面が一つだけで、画面遷移・戻る動作はすべて同一WebView内で完結します。

NativePHPモバイルアプリには常にたった一つのネイティブWebViewコントロールしか存在せず、アプリ内のすべての画面描画はこのWebコンテナ内で行われます。

  • 画面遷移、ルーティング切り替え、前画面へ戻る、モーダル、サブ画面、SPA切り替えなど、すべて新規WebViewを作成しません。これによりメモリ消費を抑える設計となっています。
  • Android / iOS標準の複数ページスタック、Activity/ViewControllerによる画面階層は存在しません;
  • 複数の画面に見えるUIは、Laravel / Livewire / Vue Routerなどのフロントルーティングにより同一WebView内でDOMを切り替えているだけで、通常のWeb SPAと同じ動作ロジックです。

1 Viewport設定(metaタグによる画面レイアウト適応)

モバイルWeb開発経験のある方なら、この設定に馴染みがあると思います。

WebViewは通常のブラウザと同様にViewport(表示領域)の概念を持ち、metaタグで制御します。記述方法は一般的なWebページと完全に同一です。

<meta name="viewport" content="width=device-width, initial-scale=1">Code language: HTML, XML (xml)

HTMLまたはBlade PHPファイルのhead内にこのmetaタグを記述してください。現在のモバイルWebサイトではほぼ標準搭載されており、スマホ画面に最適化する役割があります。記述しない場合、PCブラウザ基準で描画され文字が細く見えたり、レイアウトが崩れたりします。スマホは高DPI解像度のため、適応設定が必須です。

実際のWebサイトで確認できます。NativePHP公式ドキュメントページ:Web View – NativePHP mobile v3 – NativePHPを開き、右クリックからページソースを確認すると記載されています。

この設定には2つのプロパティがあります。

width=device-width:ページ幅をデバイス物理画面幅に一致させる

initial-scale=1:初期表示倍率を1倍(拡大・縮小なし)に固定

2 ピンチズームを無効化(ネイティブアプリ風の操作感にする)

純粋なAndroid・iOSネイティブアプリは二本指による拡大縮小(ピンチズーム)に対応していませんが、スマホブラウザは標準で許可されています。NativePHPアプリをネイティブライクな挙動にするには、このズーム操作を禁止する必要があります。

モバイルアプリ開発時は画面表示を厳密に制御するため、ユーザーによる手動ズームを無効にし、ネイティブアプリと同じ操作感を再現します。

上記のviewportタグに下記の属性を追加します。

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">Code language: HTML, XML (xml)

user-scalable=no:手動ズームジェスチャーを無効にする

3 画面端まで描画 Edge-to-Edge(ノッチ/曲面画面対応事前設定)

UIデザインの自由度を最大化するため、WebViewは既定で画面全体を描画領域とします。HTML/CSS/JSだけで前面に任意の要素を配置可能です。

ただし画面全体が利用可能なわけではありません。多くのスマホにはカメラノッチ、画面角丸、曲面ディスプレイ、iPhoneのダイナミックアイランドなどが存在し、これらの領域は描画範囲に含まれるもののコンテンツが隠れたりタップ不可になったりします。

異形画面に適応させるため、meta Viewportタグに viewport-fit=cover を追加し、安全領域(Safe Area Insets)のスタイルと組み合わせて使用します。

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, viewport-fit=cover">Code language: HTML, XML (xml)

viewport-fit=cover:ノッチ、角丸部分を含む画面端まで描画を拡張。このパラメータだけではコンテンツがノッチに隠れるため、後述するSafe AreaのCSSと併用する必要があります。

安全領域 Safe Areas

安全領域とは、ハードウェア(ノッチ、角丸、ダイナミックアイランド)やシステムUI(下部ジェスチャーバー、ステータスバー)に遮られない表示エリアのことです。

デバイス起動時に自動的に安全領域のサイズが計算され、縦横画面切り替えに追従して動的に変化します。NativePHPは標準搭載のCSS変数により複数機種に対応したレイアウトを実現できます。

<!-- bodyに全体の安全領域制約を適用 -->
<body class="nativephp-safe-area">
    <!-- 上部ナビゲーションバー左右に画面角丸分の余白を確保 -->
    <div class="fixed top-0 left-0 w-full bg-red-500 pl-[var(--inset-left)] pr-[var(--inset-right)]">
        上部ナビゲーションバー
    </div>
</body>Code language: HTML, XML (xml)
  • --inset-top 上部安全余白(ステータスバー / ノッチ高さ)
  • --inset-bottom 下部安全余白(ジェスチャーバー高さ)
  • --inset-left 左側曲面/角丸余白
  • --inset-right 右側曲面/角丸余白

上記のCSS変数はNativePHP Mobileに標準実装されており、フレームワークが自動注入するため、外部CSSライブラリを導入する必要はありません。

一括適用CSSクラス:nativephp-safe-area

HTMLのルートコンテナにこのクラスを付与するだけで、コンテンツが自動的に安全領域内に収まり、開発工数を削減できます。上記コードを参照してください。

実際に未対応の状態と比較して動作を確認します。まず公式サンプルで原理を理解し、後で実機で検証します。まず安全領域を設定していない例です。

<div class="fixed top-0 left-0 w-full bg-red-500">
    ...
</div>Code language: HTML, XML (xml)

画像を見ると、上部タイトルバーがカメラノッチに重なって隠れてしまっています。

横画面に切り替えるとさらに状況が悪化します。下図を参照。

横画面時に左右に大きな空白が発生し、上部バーが画面一杯に広がらず見た目が悪くなります。

bodyタグに標準クラスを追加して安全領域設定を適用する例:

<body class="nativephp-safe-area">
<div class="fixed top-0 left-0 w-full bg-red-500 pl-[var(--inset-left)] pr-[var(--inset-right)]">
    ...
</div>Code language: HTML, XML (xml)

画面全体にUIがフィットし、見た目が大幅に改善されます。

コード編集実習

前回のレッスンで使用したwelcome.blade.phpファイルを編集します。

body内のコンテンツを下記に置き換えます。サンプルではBootstrapに似たフロントUIライブラリTailwindを使用しています。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>{{ config('app.name', 'Mimi') }} - Built with NativePHP : welcome to foxdevelop.com</title>

    </head>
    <body>
        <div class="fixed top-0 left-0 w-full bg-red-500">
			上部ナビゲーションバー
		</div>
    </body>
</html>
Code language: HTML, XML (xml)

ファイル保存後、CMDでプロジェクトルートディレクトリに移動し、下記コマンドを実行します。

php artisan native:jumpCode language: CSS (css)
D:\phpproject\my-app>php artisan native:jumpCode language: CSS (css)

プレビューURL:http://127.0.0.1:8000

PCブラウザだけではモバイル適応の効果を確認できないため、実機で動作確認する必要があります。

実機デバッグ手順

通常のAndroidアプリ開発と同様、Androidスマホを用意しUSBケーブルでPCに接続し、スマホ側で開発者オプションを有効にします。有効化方法は検索すれば簡単に確認可能です。またADBツールをインストールする必要があります。ADBはGoogle製のPCからスマホを操作するツールで、Android Studioに同梱されています。

Android Studioを完全インストールし、Android SDK、SDK Platform Tools(ADB同梱)を導入します。

ADBが正常にインストールされたか確認:

ターミナルに下記コマンドを入力:adb devices

D:\phpproject\my-app>adb devices
List of devices attached
a34354354354352    deviceCode language: PHP (php)

上記出力例はスマホが正常接続されている状態です。

プロジェクトフォルダに移動し、CMDにて下記コマンドを実行しAndroidアプリをビルド・インストール:php artisan native:run android

D:\phpproject\my-app>php artisan native:run android

  Running NativePHP for Android

 Build log: D:\phpproject\my-app\nativephp\android-build.log

  Updating Android configuration ....................................................................... 903.01ms DONE
  Copying Laravel source .................................................................................... 18s DONE
  Installing Composer dependenciesCode language: PowerShell (powershell)

ビルド時にKotlin、Gradleなど各種依存パッケージが自動インストールされるため、安定したネットワーク環境が必要です。

プロキシ環境を使用する場合は、プロジェクト内の下記パスの設定ファイルを編集します:D:\phpproject\my-app\nativephp\android\gradle\wrapper\gradle-wrapper.properties

Gradleのダウンロード先を国内ミラーサイトに置き換える例:

#Mon Feb 10 07:33:27 EST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
#distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
distributionUrl=https\://mirrors.aliyun.com/maven/gradle/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Code language: Properties (properties)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です