Подключенные дисплеи расширяют возможности работы с окнами рабочего стола на стандартные телефоны, предоставляя пользователям доступ к большим экранам со своих мобильных устройств. Эта возможность открывает новые перспективы для взаимодействия с приложениями и повышения производительности труда.
Все уникальные особенности оконного режима рабочего стола применимы и к подключенным дисплеям. При подключении телефона к дисплею состояние телефона остается неизменным, и на подключенном дисплее запускается пустая сессия рабочего стола. Устройство и дисплей действуют как две отдельные системы, с приложениями, специфичными для каждого дисплея.
Если подключить устройство с поддержкой оконного режима, например планшет, к внешнему монитору, сессия рабочего стола будет отображаться на обоих дисплеях. В этом случае два дисплея будут функционировать как единая непрерывная система. Такая конфигурация позволяет окнам, контенту и курсору свободно перемещаться между двумя дисплеями.
Для эффективной поддержки подключенных дисплеев необходимо уделить внимание нескольким аспектам проектирования и реализации вашего приложения. Следующие рекомендации обеспечат плавную и продуктивную работу пользователя.
Обработка динамических изменений отображения
Многие приложения создаются с предположением, что объект Display и его характеристики не будут меняться в течение жизненного цикла приложения. Однако, когда пользователь подключает или отключает внешний монитор, или даже перемещает окно приложения между дисплеями, базовый объект Display , связанный с контекстом или окном вашего приложения, может измениться. Свойства дисплея, такие как размер, разрешение, частота обновления, поддержка HDR и плотность, могут быть разными. Например, если вы жестко зададите значения, основанные на экране телефона, ваши макеты, скорее всего, будут некорректно отображаться на внешнем дисплее.
Внешние дисплеи также могут иметь совершенно разную плотность пикселей. Вам необходимо убедиться, что ваше приложение корректно реагирует на изменения плотности . Это включает в себя использование пикселей, не зависящих от плотности (dp), для компоновки, предоставление ресурсов, специфичных для плотности, и обеспечение соответствующего масштабирования пользовательского интерфейса.
Если приложение работает на внешнем дисплее, когда тот отключен, система перемещает приложение на основной дисплей. Это перемещение запускает изменения конфигурации — например, изменение размера и плотности экрана — что может привести к повторному созданию приложения. Ваше приложение должно обрабатывать изменения конфигурации, сохраняя и восстанавливая состояние пользовательского интерфейса , чтобы предотвратить потерю данных или путаницу в пользовательском интерфейсе.
Используйте правильный контекст.
Использование правильного контекста имеет решающее значение в средах с несколькими дисплеями. При доступе к ресурсам контекст действия (который отображается) отличается от контекста приложения (который не отображается).
Контекст активности содержит информацию о дисплее и всегда корректируется в соответствии с областью отображения, в которой появляется активность. Это позволяет получить корректную информацию о плотности отображения или метриках окна вашего приложения. Всегда используйте контекст активности (или другой контекст пользовательского интерфейса) для получения информации о текущем окне или дисплее. Это также влияет на некоторые системные API, которые используют информацию из контекста.
В Jetpack Compose вы можете получить доступ к информации, специфичной для каждого дисплея, используя объекты CompositionLocal , такие как LocalConfiguration.current и LocalDensity.current . Когда активность или окно перемещаются между дисплеями, конфигурация устройства изменяется, запуская перекомпозицию с новыми метриками дисплея. Объекты CompositionLocal позволяют вашему пользовательскому интерфейсу плавно адаптироваться.
Получить информацию для отображения
Вы можете использовать класс Display для получения такой информации, как размер дисплея, плотность пикселей или флаги. Используйте системную службу DisplayManager для получения списка доступных дисплеев. Чтобы определить внешние дисплеи, отфильтруйте Display.DEFAULT_DISPLAY , который обычно соответствует встроенному экрану телефона или планшета:
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val displays = displayManager.getDisplays()
// The default display is 0. External displays have other IDs.
val externalDisplays = displays.filter { it.displayId != Display.DEFAULT_DISPLAY }
Управление запуском и настройкой действий
При использовании подключенных дисплеев приложения могут указывать, на каком дисплее приложение должно работать при запуске или при создании другой активности. Это поведение зависит от режима запуска активности, определенного в файле манифеста, а также от флагов и параметров намерений, установленных сущностью, запускающей активность.
Когда активность переключается на дополнительный экран, в вашем приложении может произойти обновление контекста, изменение размера окна, а также изменения конфигурации и ресурсов. Если активность обрабатывает изменение конфигурации, она получает уведомление в onConfigurationChanged() . В противном случае активность перезапускается.
Если выбранный режим запуска для действия допускает несколько экземпляров, запуск на дополнительном экране может создать новый экземпляр этого действия. Оба действия возобновляются одновременно, что может быть полезно в некоторых сценариях многозадачности.
Запустить активность на определенном экране можно с помощью ActivityOptions . Обратите внимание, что launchDisplayId требуется Android 8 (уровень API 26) или выше.
// Get DisplayManager and find the first external display.
val displayManager = getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
val externalDisplayId = displayManager.displays
.firstOrNull { it.displayId != Display.DEFAULT_DISPLAY }
?.displayId
// If an external display is found, launch the activity on it.
if (externalDisplayId != null) {
val intent = Intent(this, MySecondaryActivity::class.java)
val options = ActivityOptions.makeBasic()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
options.launchDisplayId = externalDisplayId
}
startActivity(intent, options.toBundle())
} else {
// Optionally, handle the case where no external display is connected.
}
Избегайте добавления устройств в списки разрешенных устройств.
Иногда приложения ограничивают доступ к пользовательскому интерфейсу и функциям для больших экранов только для определенных устройств, используя список разрешенных устройств или проверяя файл BUILD.MODEL и размер встроенного дисплея. Такой подход неэффективен для подключенных дисплеев, поскольку к большому экрану можно подключить практически любое устройство, и модель устройства не меняется при подключении внешнего дисплея.
Вместо использования списков разрешенных окон или проверки BUILD.MODEL и встроенного размера экрана, проверяйте метрики окна или возможности устройства во время выполнения, чтобы принимать решения по пользовательскому интерфейсу. Используйте API Jetpack WindowManager или классы размеров окон для создания адаптивных макетов для различных размеров и плотности экрана.
Поддержка внешних периферийных устройств
При подключении к внешнему дисплею пользователи часто создают среду, более похожую на рабочий стол. Это часто включает использование внешних клавиатур, мышей, тачпадов, веб-камер, микрофонов и динамиков. Вам необходимо обеспечить бесперебойную работу вашего приложения с этими периферийными устройствами. Это включает обработку сочетаний клавиш, управление взаимодействием указателя мыши, корректную поддержку внешних камер или микрофонов и учет маршрутизации аудиовыхода. Для получения более подробной информации см. раздел «Совместимость ввода на больших экранах» .
Повышение производительности пользователей
Подключенные дисплеи предоставляют значительные возможности для повышения производительности пользователей . Теперь у вас есть инструменты для создания мобильных приложений, которые могут предложить возможности, сопоставимые с настольными приложениями. Рассмотрите возможность внедрения следующих функций для повышения производительности пользователей :
- Предоставьте пользователям возможность открывать несколько экземпляров одного и того же приложения. Это бесценно для таких задач, как сравнение документов, управление различными переписками или одновременный просмотр нескольких файлов.
- Предоставьте пользователям возможность обмениваться большими объемами данных между вашим приложением и другими приложениями с помощью функции перетаскивания .
- Внедрите надежную систему управления состоянием , чтобы помочь пользователям поддерживать рабочий процесс при изменении конфигурации.
Следуя этим рекомендациям и используя предоставленные примеры кода, вы сможете создавать приложения, которые легко адаптируются к подключенным дисплеям, предлагая пользователям более насыщенный и продуктивный опыт.