Представление страницы WebView

Представление страницы WebView

На прошлом занятии мы узнали, где находится интерфейс нашей страницы. Сейчас продолжим обучение.

Понимание единственного нативного веб-представления (WebView)

Все мобильные приложения, созданные на NativePHP, используют одно единственное нативное веб-представление (WebView) как основной контейнер. С помощью WebView вы можете создавать интерфейс приложения на любых знакомых фронтенд веб-технологиях. По сути это обычная веб-страница, встроенный браузер отвечает за её отрисовку.

По умолчанию WebView занимает всю видимую область экрана. При запуске камеры её интерфейс временно перекрывает WebView.

Основная идея NativePHP: бэкенд на PHP + гибридная разработка на любом фронтенд стеке (Vue, jQuery, Tailwind и т.д.)

WebView всегда отображается поверх всего; только полноэкранные режимы камеры или встроенного браузера скрывают его. Весь видимый пользователю интерфейс рисуется через WebView.

Низкоуровневая архитектура NativePHP Mobile: один контейнер WebView без многослойных нативных страниц. То есть в NativePHP только одна страница, все переходы и возвраты работают внутри одной WebView.

Любое мобильное приложение NativePHP содержит только один единственный нативный элемент управления WebView. Всё отображение страниц приложения происходит внутри этого одного веб-контейнера:

  • Переход по страницам, маршрутизация, возврат на предыдущую страницу, всплывающие окна, подстраницы и переключение SPA никогда не создают вторую WebView. Этот подход снижает потребление оперативной памяти.
  • Отсутствует нативный стек страниц Android/iOS и иерархия Activity/ViewController;
  • Множество «страниц», которые мы видим — это лишь переключение DOM внутри одной WebView через фронтенд-маршруты (Laravel / Livewire / Vue Router и др.), логика полностью совпадает с обычными одностраничными веб-приложениями.

1 Настройка Viewport (управление адаптацией экрана через тег meta)

Все, кто разрабатывал мобильные сайты, знакомы с этой настройкой.

Как и обычный браузер, WebView имеет концепцию Viewport (область просмотра), управляемую тегом meta с синтаксисом, полностью совпадающим с классическими веб-страницами.

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

Добавьте этот meta-тег в ваш HTML или Blade PHP файл. Сейчас почти все сайты используют эту конфигурацию для адаптации под мобильные браузеры. Без неё страница рендерится под разрешение ПК: шрифт выглядит тонким, вёрстка искажается, так как у телефонов высокое разрешение DPI.

Проверить можно на любом сайте, например официальная документация NativePHP: Web View — NativePHP mobile v3 — NativePHP. Правой кнопкой мыши откройте исходный код страницы и увидите этот тег.

Эта конфигурация включает два основных атрибута:

width=device-width: Ширина страницы равна физической ширине экрана устройства

initial-scale=1: Начальный масштаб отображения 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 (предварительная настройка для вырезов и изогнутых дисплеев)

Для максимальной свободы дизайна интерфейса WebView по умолчанию заполняет весь экран. Только средства HTML/CSS/JS позволяют размещать контент в любом месте переднего плана.

Но не вся поверхность экрана доступна для использования. Большинство устройств имеют вырез под фронтальную камеру, скруглённые углы, изогнутые края или Dynamic Island на iPhone. Эти зоны входят в область viewport, но перекрывают контент и не поддерживают нажатия.

Для адаптации экранов нестандартной формы добавьте viewport-fit=cover в meta-тег viewport и используйте вместе с безопасными отступами (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: Позволяет отрисовывать страницу до самых краёв экрана (включая вырезы и скруглённые углы). Одного этого параметра недостаточно — контент будет перекрываться вырезом камеры, обязательно используйте вместе с CSS стилями безопасных зон, см. ниже.

Безопасные зоны Safe Areas

Безопасные зоны — это видимые участки экрана, не перекрываемые: они не закрыты аппаратными элементами (скруглённые углы, вырез камеры, Dynamic Island) и постоянными системными интерфейсами (нижняя панель жестов, статус-бар).

Устройство автоматически вычисляет границы безопасных зон и динамически подстраивается при переключении портретной и ландшафтной ориентации. 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>

На изображении видно, что верхняя панель заголовка полностью перекрыта вырезом под фронтальную камеру.

В ландшафтном режиме ситуация ещё хуже, см. изображение ниже:

При горизонтальной ориентации по бокам появляются большие пустые участки, верхняя панель не заполняет весь экран, внешний вид получается неаккуратным.

С настроенными безопасными зонами добавьте стандартный класс к тегу 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)

Интерфейс полностью заполняет экран, внешний вид значительно улучшается.

Редактирование кода

Отредактируем примерный файл с прошлого занятия: welcome.blade.php

Замените всё содержимое внутри тега body на код ниже. Мы используем Tailwind — фронтенд UI библиотеку, аналогичную Bootstrap.

<!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)

Сохраните файл, откройте командную строку в папке проекта и выполните команду:

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

Ссылка для предпросмотра: http://127.0.0.1:8000

Предпросмотр в браузере ПК не показывает эффект мобильной адаптации, нужно тестировать на реальном устройстве.

Отладка на реальном устройстве

Процедура совпадает с разработкой обычных Android приложений: подготовьте Android телефон, подключите к компьютеру по USB-кабелю, включите режим разработчика на телефоне (инструкцию легко найти в интернете). Также установите утилиту ADB от Google для управления телефоном с ПК, она поставляется вместе с 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)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *