Оптимизация андроид приложения под разные экраны
Если быстродействие вашего мобильного устройства снизилось, не спешите покупать новый девайс. Оптимизация андроид позволит увеличить его производительность. Мы предложим вам несколько эффективных вариантов решения проблемы и поделимся простыми советами. Следуя им, вы избежите снижения быстродействия своего мобильного гаджета в будущем.
Одни способы предполагают изменение настроек и параметров, другие — использование сторонних программ, третьи — следование незатейливым рекомендациям, а четвертые — обычную чистку. Лучше всего наводить порядок комплексно. Только так можно вернуть устройству «заводскую» производительность и использовать все преимущества операционной системы андроид вашего смартфона или планшета.
Используем «Режим разработчика»
Этот пункт можно найти в Меню девайса. Если вы его там не обнаружили, включите режим, используя простой алгоритм. Для того чтобы его активировать, перейдите в «Настройки», а затем в раздел «Об устройстве» (о смартфоне, планшете). Найдите пункт «Номер сборки» и щелкните по нему 7-10 (!) раз. Режим, предназначенный для более гибких настроек, включен!
В «инженерном» меню нас интересуют три пункта. Во-первых, мы должны активировать «Принудительную визуализацию». Это ускорит работу графического процессора и снимет нагрузку с основного. Во-вторых, мы активируем пункт «Отключение аппаратного наложения». В-третьих, снизим количество «Фоновых процессов» до трех. Это позволит увеличить производительность, но не снизит многозадачность. И последние настройки связаны с анимацией. Если устройство не может похвастаться мощными характеристиками, лучше всего отключить анимацию. Ничего больше не активируйте в этом режиме, если не обладаете достаточными знаниями!
Это был первый способ оптимизации андроида, в котором мы поменяли настройки. Идем дальше.
Обновляем Android
Менять прошивку мобильного устройства важно. И это не прихоть разработчиков, а необходимость. Ведь с каждой новой версией ОС совершенствуется: исправляются проблемы, недочеты, баги. Чтобы проверить актуальность программного обеспечения, откройте «Настройки» и найдите пункт «О телефоне». Далее зайдите на сайт производителя и поищите обновленную версию прошивки.
Используем Clean Master или любой другой мастер очистки андроид
Мастер очистки — отличный инструмент, который по праву считается средством №1 по оптимизации андроид. С помощью бесплатного приложения вы не только «наведете порядок» в мобильном устройстве. Вы повысите безопасность, конфиденциальность данных благодаря антивирусной онлайн защите, сэкономите заряд аккумулятора и значительно ускорите работу операционной системы.
Clean Master чистит девайс от ненужных файлов, удаляет или блокирует уведомления и приложения, освобождает ОЗУ, ускоряет работу. Также он снижает температуру процессора и аккумулятора, экономит энергию, управляет фоновыми процессами. И это неполный перечень функций «мастера очистки»!
Сбрасываем настройки
Если ни очистка с помощью стороннего приложения, ни обновление программного обеспечения ничего не дали, восстановите устройство. Для этого нужно сбросить его настройки до первоначальных — заводских. Этот способ поможет вам не только оптимизировать гаджет, но и выяснить причину снижения производительности. Если вы через время вновь загрузите контент, проще будет установить, что именно привело к замедленной работе телефона или планшета. В любом случае, перегружать устройство информацией не рекомендуется. А если по-другому не выходит, тогда время от времени следует удалять ненужные, устаревшие данные.
Внимание! Перед оптимизацией андроида таким способом не забудьте сделать резервное копирование личной информации!
Используем флеш-память
Купите объемную и высокоскоростную microSD карту, храните на ней основную часть контента, освобождая внутреннюю память устройства. Это отличный вариант для тех пользователей, у кого много игр, приложений, музыки, графики. Ведь чем больше свободной памяти, тем быстрее выполняет задачи программное обеспечение мобильного гаджета. Также старайтесь минимизировать использование менеджеров закачек, например, BitTorrent.
Удаляем визуальные эффекты: виджеты и «живые» обои
Удаляем ненужные программы
Чем дольше мы пользуемся мобильным устройством, тем больше приложений хранится в его памяти. При этом часть из них абсолютно не используется. Проведите ревизию и удалите все лишнее — то, во что давно не играете, то, что давно не используете. И даже, если спустя время, понадобится какое-то приложение, его всегда можно загрузить с Play маркета или другого источника.
Итак, оптимизация андроид проведена. Теперь проверьте, насколько эффективно и быстро работает мобильная операционная система. Вы довольны результатом?
В этом уроке рассказывается, как создать макет, который адаптируется к разным размерам экрана, используя масштабируемые представления, объекты RelativeLayout , квалификаторы размера и ориентации, фильтры псевдонимов и растровые изображений формата nine-patch.
Код, приведенный в уроке, взят из учебного приложения, в котором демонстрируются способы оптимизации для разных экранов. Вы можете загрузить его здесь и использовать части кода в собственном приложении.
В этом уроке описаны следующие аспекты обеспечения совместимости интерфейса с разными экранами:
- обеспечение способности макета адаптироваться к размеру экрана;
- выбор макета интерфейса, отвечающего конфигурации экрана;
- контроль правильности применяемого макета;
- использование масштабируемых растровых изображений.
Использование параметров wrap_content и match_parent
Чтобы создать масштабируемый макет, способный адаптироваться к разным экранам, используйте в качестве значений ширины и высоты отдельных компонентов представления параметры "wrap_content" и "match_parent" . Если используется "wrap_content" , для ширины или высоты представления устанавливается минимальное значение, позволяющее уместить содержание на экран, а параметр "match_parent" (известный как "fill_parent" в API до 8 уровня) служит для растягивания компонента по размеру родительского представления.
Если указать параметры "wrap_content" и "match_parent" вместо строго заданных размеров, в представлениях будет использоваться минимально необходимое место или они будут растягиваться на всю доступную длину и ширину соответственно. Например:
< LinearLayout xmlns : android = "http://schemas.android.com/apk/res/android" android : name = "com.example.android.newsreader.HeadlinesFragment"Обратите внимание на то, что в коде учебного приложения размеры компонентов заданы с помощью параметров "wrap_content" и "match_parent" . В результате макет правильно отображается на экранах разных размеров при разных ориентациях.
Например, вот так он выглядит в вертикальной и горизонтальной ориентациях. Обратите внимание на то, как размеры компонентов автоматически адаптируются к длине и ширине:
Рисунок 1. Приложение News Reader при вертикальной (слева) и горизонтальной (справа) ориентации.
Использование объекта RelativeLayout
С помощью вложенных экземпляров объекта LinearLayout и параметров "wrap_content" и "match_parent" можно создавать достаточно сложные макеты. Однако LinearLayout не дает возможности точно управлять взаимным расположением дочерних представлений: в LinearLayout они просто помещаются в ряд друг за другом. Если необходимо расположить дочерние представления иным образом, используйте объект RelativeLayout , позволяющий задать относительные позиции компонентов. Например, одно дочернее представление можно выровнять по левому краю экрана, а другое – по правому.
< RelativeLayout xmlns : android = "http://schemas.android.com/apk/res/android"На рис. 2 показано, как этот макет выглядит на экране QVGA.
Рисунок 2. Скриншот экрана QVGA (маленького размера).
На рис. 3 показано, как он выглядит на экране с большей диагональю.
Рисунок 3. Скриншот экрана WSVGA (большего размера).
Обратите внимание: несмотря на изменение размера компонентов их взаимное расположение остается прежним, так как оно задано объектом RelativeLayout.LayoutParams .
Использование квалификаторов размера
Масштабируемые или относительные макеты, один из которых продемонстрирован выше, имеют свои ограничения. Хотя они позволяют создать интерфейс, способный адаптироваться к разным экранам за счет растягивания пространства внутри и вокруг компонентов, пользователю может оказаться не слишком удобно работать с таким интерфейсом. Поэтому в приложении должен использоваться не один масштабируемый макет, а несколько альтернативных вариантов для разных конфигураций экрана. Их можно создать с помощью квалификаторов конфигураций, которые позволяют оперативно выбирать ресурсы, отвечающие текущим параметрам экрана (например, разные варианты макетов для экранов разных размеров).
Многие приложения отображаются на больших экранах в двухпанельном режиме, при котором список элементов расположен в одной панели, а их содержание открывается в другой. Такой режим просмотра удобен на достаточно больших экранах планшетных ПК и телевизоров, однако на экране телефона эти панели следует отображать по отдельности. Для каждого режима просмотра нужно создать отдельный файл.
-
res/layout/main.xml , однопанельный макет (по умолчанию):
Обратите внимание, что во втором случае в названии каталога использован квалификатор large . Этот макет будет выбран на устройствах, экраны которых считаются большими (например, 7 дюймов и более). Первый макет (без квалификаторов) будет выбран для устройств с маленьким экраном.
Использование квалификатора Smallest-width
Он позволяет определять экраны с заданной минимальной шириной в dp. Например, типичный планшетный ПК с экраном 7 дюймов имеет минимальную ширину 600 dp, и если вы хотите, чтобы приложение работало на нем в двухпанельном режиме (а на меньших экранах в однопанельном), используйте два макета из предыдущего раздела, но вместо квалификатора размера large укажите sw600dp . В таком случае на экранах, минимальная ширина которых составляет 600 dp, будет использоваться двухпанельный макет.
-
res/layout/main.xml , однопанельный макет (по умолчанию):
Это означает, что на устройствах, минимальная ширина экрана которых не меньше 600 dp, будет выбран layout-sw600dp/main.xml (двухпанельный макет), а на экранах меньшего размера – layout/main.xml (однопанельный макет).
Следует учесть, что на Android-устройствах до версии 3.2 квалификатор sw600dp не будет работать, поэтому для них по-прежнему нужно использовать large . Таким образом, вам потребуется еще один файл с названием res/layout-large/main.xml , идентичный файлу res/layout-sw600dp/main.xml . В следующем разделе вы познакомитесь с методом, который позволяет избежать дублирования таких файлов макета.
Использование псевдонимов макетов
Квалификатор Smallest-width работает только на устройствах Android 3.2 или более поздних версий. Для совместимости с более ранними устройствами по-прежнему следует использовать абстрактные размеры (small, normal, large и xlarge). Например, чтобы интерфейс открывался в однопанельном режиме на телефонах и в многопанельном на планшетных ПК с 7-дюймовым экраном, телевизорах и других крупных устройствах, подготовьте следующие файлы:
- res/layout/main.xml: однопанельный макет;
- res/layout-large: многопанельный макет;
- res/layout-sw600dp: многопанельный макет.
Последние два файла идентичны: один из них предназначен для устройств Android 3.2 и новее, а второй для более старых планшетных ПК и телевизоров на платформе Android.
Чтобы не создавать дубликаты файлов и упростить процесс поддержки приложения, используйте псевдонимы. Например, можно определить следующие макеты:
- res/layout/main.xml (однопанельный макет);
- res/layout/main_twopanes.xml (двухпанельный макет).
Затем добавьте следующие два файла:
< item name = "main" type = "layout" > @ layout / main_twopanes < / item > < item name = "main" type = "layout" > @ layout / main_twopanes < / item >Содержание последних двух файлов одинаково, но сами по себе они не определяют макет. Они служат для того, чтобы назначить файл main в качестве псевдонима main_twopanes . Так как в них используются селекторы large и sw600dp , они применяются к планшетным ПК и телевизорам на платформе Android независимо от версии (для версий до 3.2 используется large , а для более новых – sw600dp ).
Использование квалификаторов ориентации
Хотя некоторые макеты одинаково хорошо смотрятся в вертикальной и горизонтальной ориентациях, в большинстве случаев интерфейс все же приходится адаптировать. Ниже показано, как изменяется макет в приложении News Reader в зависимости от размера и ориентации экрана.
- Маленький экран, вертикальная ориентация: однопанельный вид с логотипом.
- Маленький экран, горизонтальная ориентация: однопанельный вид с логотипом.
- Планшетный ПК с 7-дюймовым экраном, вертикальная ориентация: однопанельный вид с панелью действий.
- Планшетный ПК с 7-дюймовым экраном, горизонтальная ориентация: двухпанельный вид с панелью действий.
- Планшетный ПК с 10-дюймовым экраном, вертикальная ориентация: двухпанельный вид (узкий вариант) с панелью действий.
- Планшетный ПК с 10-дюймовым экраном, горизонтальная ориентация: двухпанельный вид (широкий вариант) с панелью действий.
- Телевизор, горизонтальная ориентация: двухпанельный вид с панелью действий.
Каждый из этих макетов определен в XML-файле в каталоге res/layout/ . Чтобы сопоставить их с определенными конфигурациями экрана, в приложении используются псевдонимы:
< LinearLayout xmlns : android = "http://schemas.android.com/apk/res/android" android : name = "com.example.android.newsreader.HeadlinesFragment" < LinearLayout xmlns : android = "http://schemas.android.com/apk/res/android" android : name = "com.example.android.newsreader.HeadlinesFragment" < LinearLayout xmlns : android = "http://schemas.android.com/apk/res/android" android : name = "com.example.android.newsreader.HeadlinesFragment" android : name = "com.example.android.newsreader.ArticleFragment" < LinearLayout xmlns : android = "http://schemas.android.com/apk/res/android" android : name = "com.example.android.newsreader.HeadlinesFragment" android : name = "com.example.android.newsreader.ArticleFragment"После того как все возможные макеты определены, остается сопоставить каждый из них с подходящей конфигурацией, используя квалификаторы конфигураций. Воспользуемся псевдонимами макетов:
< item name = "main_layout" type = "layout" > @ layout / onepane_with_bar < / item > < item name = "main_layout" type = "layout" > @ layout / twopanes < / item > < item name = "main_layout" type = "layout" > @ layout / onepane < / item > < item name = "main_layout" type = "layout" > @ layout / twopanes < / item > < item name = "main_layout" type = "layout" > @ layout / twopanes_narrow < / item >Использование растровых изображений nine-patch
Чтобы интерфейс был совместим с экранами разных размеров, используемые в нем графические элементы также должны быть адаптированы соответствующим образом. Например, фон кнопки должен одинаково хорошо выглядеть независимо от ее формы.
Если использовать для компонентов, размеры которых меняются, обычные изображения, то они будут равномерно сжиматься и растягиваться, и результат будет далек от идеального. Решением являются растровые изображения формата nine-patch – специальные PNG-файлы, содержащие информацию о том, какие области можно растягивать, а какие нет.
Создавая растровые изображения для масштабируемых компонентов, обязательно используйте формат nine-patch. На рис. 4 показано обычное растровое изображение (увеличенное в 4 раза для наглядности), которое мы переведем в формат nine-patch.
Рисунок 4. button.jpg
Откройте его с помощью утилиты draw9patch , входящей в комплект разработчика (в каталоге tools/ ). Установите метки на левом и верхнем краях, чтобы ограничить области, которые можно растягивать. Можно также провести линию вдоль правого и нижнего краев, как показано на рис. 5, чтобы отметить области, в которых содержание должно быть зафиксировано.
Рисунок 5. button.9.jpg
Обратите внимание на черные пиксели по краям. Метки у верхней и левой границ обозначают те области, которые можно растягивать, а метки у правой и нижней границ – те, куда должно быть помещено содержание.
Также обратите внимание на расширение .9.jpg . Оно должно быть задано именно в таком виде, чтобы система могла определить, что это формат nine-patch, а не обычный PNG-файл.
При применении этого фона к компоненту (с помощью android:background="@drawable/button" ) изображение будет растянуто по размеру кнопки, как показано на рис. 6.
Рисунок 6. Кнопки разных размеров с файлом фона button.9.jpg в формате nine-patch.
Привет, Хабр! Представляю вашему вниманию перевод статьи Tuning your apps and games for long screen devices автора Fred Chung.
В последние месяцы растет тенденция к тому, что производители телефонов представляют новые устройства с длинным экраном (более 16: 9), многие из которых имеют закругленные углы. Pixel 2 XL и Huawei Mate 10 Pro — всего лишь два из множества примеров. Эти особенности экрана могут принести пользователям впечатляющий опыт, но они обращают внимание на приложения и игры, которые не используют экран длинного формата на новых устройствах. Поэтому для разработчиков важно оптимизировать такие экраны. Давайте посмотрим на соответствующую поддержку, предоставляемую ОС Android.
Оптимизация для экранов с длинным соотношением сторон
Большинство приложений, использующих стандартные виджеты пользовательского интерфейса, скорее всего, будут работать на этих устройствах. В документации Android уточняются методы для гибкой работы на экранах разных размеров. Однако некоторые игры и приложения с пользовательскими интерфейсами могут столкнуться с проблемами из-за неправильных предположений относительно определенных пропорций. Мы разделяем несколько типичных проблем, с которыми сталкиваются разработчики, поэтому вы можете обратить внимание на те, которые относятся к вам:
- Определенные стороны экрана обрезаны. Из-за этого любые графические элементы или элементы пользовательского интерфейса в затронутых областях выглядят неполными.
- Сенсорные цели смещаются от элементов пользовательского интерфейса (например, кнопок). Пользователи могут путать элементы
- В полноэкранном режиме на округлых углах устройств любые элементы пользовательского интерфейса, очень близкие к углам, могут находиться вне изогнутой области просмотра углов. Представьте, что нажатие на кнопку «Покупка» коммерческого приложения затруднено? Мы рекомендуем ссылаться на рекомендации по проектированию материалов, оставив боковые поля 16dp в макетах.
Targets API level 26 или выше: используйте атрибуты
Targets API level 25 или ниже: используйте метаданные
Обратите внимание, что максимальные значения соотношения сторон будут соблюдаться только в том случае, если ваши действия не поддерживают
Системные почтовые ящики в приложении используются когда объявленное максимальное соотношение сторон меньше экрана устройства.
Примите во внимание возможность использования параллельных действий
Устройства с длинным соотношением сторон обеспечивают еще больше возможностей использования нескольких окон, что может повысить производительность пользователей. Начиная с Android 7.0, платформа предлагает стандартный способ для разработчиков реализовывать многооконный режим на поддерживаемых устройствах, а также выполнять перетаскивание данных между действующими окнами. Подробнее см. В документации.
Тестирование имеет решающее значение. Если у вас нет доступа к одному из устройств с длинным экраном, обязательно проверьте на эмуляторе необходимые свойства экрана и разрешения, которые описаны в документации эмулятора.
Мы знаем, что вы хотите порадовать своих пользователей устройствами с длинным экраном. С помощью нескольких шагов вы сможете гарантировать, что ваши приложения и игры будут в полной мере использовать эти устройства!
Android работает на многих разных устройствах, каждый из которых имеет широкий спектр разрешений, размеров экрана и плотности экрана. Android выполнит масштабирование и измените размер, чтобы приложение работало на этих устройствах, но это может привести к неоптимальному взаимодействии с пользователем. Например, изображения могут выглядеть размытыми, или же они могут располагаться как ожидается в представлении.
Основные понятия
Для обеспечения поддержки нескольких экранов важно понимать несколько терминов и концепций.
Размер экрана – Объем физического пространства для отображения приложения
Плотность экрана – Количество пикселей в любой заданной области экрана. Типичная единица измерения — точка на дюйм (DPI).
Решение – Общее количество пикселей на экране. При разработке приложений разрешение не так важно, как размер и плотность экрана.
Независимый от плотности пиксель (DP) – Виртуальная единица измерения, позволяющая разрабатывать макеты независимо от плотности. Эта формула используется для преобразования точки DP в экранные пиксели:
px = DP × dpi ÷ 160
Ориентация страницы – Ориентация экрана считается альбомной, если она шире, чем высота. В отличие от ориентации, книжная ориентация имеет значение, когда высота экрана превышает ширину. Ориентация может измениться в течение времени существования приложения, когда пользователь поворачивает устройство.
Обратите внимание, что первые три из этих концепций являются взаимосвязанными – . Увеличение разрешения не приводит к увеличению размера экрана. Однако при увеличении плотности и разрешения размер экрана может остаться неизменным. Такая связь между размером экрана, плотностью и разрешением усложняет поддержку экрана.
Для решения этой сложности платформа Android предпочитает использовать аппаратно-независимые пиксели (DP) для макетов экрана. Используя независимые от плотности Пиксели, элементы пользовательского интерфейса будут отображаться для одного и того же физического размера на экранах с различной плотностью.
Поддержка различных размеров и плотности экрана
Android обрабатывает большую часть работы, чтобы правильно отобразить макеты для каждой конфигурации экрана. Однако есть некоторые действия, которые можно предпринять, чтобы помочь системе.
Использование независимых от плотности пикселей вместо фактических пикселей в макетах является достаточным в большинстве случаев для обеспечения независимости от плотности. Android будет масштабировать драваблес во время выполнения до соответствующего размера. Однако возможно, что масштабирование приведет к неразмытому появлению растровых изображений. Чтобы обойти эту проблему, предоставьте альтернативные ресурсы для другой плотности. При проектировании устройств для нескольких разрешений и плотности экрана будет проще начать с более высокого разрешения или плотности изображения, а затем уменьшить масштаб.
Объявление поддерживаемого размера экрана
Объявление размера экрана гарантирует, что только поддерживаемые устройства смогут скачать приложение. Это достигается путем установки элемента поддержки-screens в файле AndroidManifest.xml . Этот элемент используется для указания того, какие размеры экрана поддерживаются приложением. Данный экран считается поддерживаемым, если приложение может правильно расположить макеты для заполнения экрана. С помощью этого элемента манифеста приложение не будет отображаться в Google Play для устройств, которые не соответствуют спецификациям экрана. Однако приложение по-прежнему будет работать на устройствах с неподдерживаемыми экранами, но макеты могут выглядеть размытыми и пикселизованным.
Поддерживаемые экранные Сиксес объявляются в файле задающий свойства/AndroidManifest.xml решения:
Измените AndroidManifest.xml , чтобы включить поддержку экранов:
Предоставление альтернативных макетов для различных размеров экрана
Альтернативные макеты позволяют настроить представление для размера экрана спеЦифк, изменяя положение или размер элементов пользовательского интерфейса компонента.
Начиная с уровня API 13 (Android 3,2), размеры экранов не рекомендуются в пользу использования квалификатора SW N DP. Этот новый квалификатор объявляет объем пространства, необходимого для данного макета. Рекомендуется, чтобы приложения, предназначенные для работы на Android 3,2 или более поздней версии, использовали эти более новые квалификаторы.
Например, если для макета требуется минимальная 700-я точка в ширину экрана, альтернативный макет будет находиться в макете папки — sw700dp:
Ниже приведены некоторые значения для различных устройств.
Обычный телефон – 320 DP: обычный телефон
Устройство с 5 "планшетом/" или "tween-анимацией" – 480 DP: например, Примечание Samsung
7 "планшетный – 600 DP: например, Барнса & благородные Нук
10 "Планшет – 720 DP: например, Ксум Motorola
Для приложений, предназначенных для уровней API до 12 (Android 3,1), макеты должны находиться в каталогах, использующих квалификаторы малого / обычного / размера / ксларже , как обобщения различных размеров экрана, доступных на большинстве устройств. Например, на рисунке ниже приведены дополнительные ресурсы для четырех различных размеров экрана:
Ниже приведено сравнение того, как более старые квалификаторы размера экрана, предшествующие API уровня 13, сравниваются с пикселями, не зависящими от плотности.
426 DP x 320 DP невелика
470 DP x 320 DP является нормальной
640 DP x 480 DP большие
960 DP x 720 DP — ксларже
Новые квалификаторы размера экрана на уровне API 13 и выше имеют более высокий приоритет, чем предыдущие квалификаторы экрана на уровнях API 12 и ниже. Для приложений, которые будут охватывать старый и новый уровни API, может потребоваться создать альтернативные ресурсы с помощью обоих наборов квалификаторов, как показано на следующем снимке экрана:
Укажите разные точечные рисунки для различной плотности экрана
Несмотря на то, что Android будет масштабировать точечные рисунки по мере необходимости для устройства, растровые изображения могут не элегантной масштабирование. они могут стать нечеткими или размытыми. Предоставление точечных рисунков, подходящих для плотности экрана, снизит эту проблему.
Например, приведенный ниже рисунок представляет собой пример проблем макета и внешнего вида, которые могут возникнуть, если не предоставлены ресурсы с указанием плотности.
Сравните это с макетом, который предназначен для ресурсов, зависящих от плотности:
Создание ресурсов с различной плотностью с помощью Android Asset Studio
Создание этих растровых изображений различной плотности может быть немного утомительным. Таким образом, Google создал интерактивную служебную программу, которая может сократить некоторые долгой, связанные с созданием этих точечных рисунков под названием Android Asset Studio.
Этот веб-сайт поможет при создании точечных рисунков, нацеленных на четыре распространенные плотности экрана, путем предоставления одного изображения. После этого Android Asset Studio создаст точечные рисунки с некоторыми настройками, а затем позволит скачать их в виде ZIP-файла.
Советы для нескольких экранов
Android работает на ошеломляющей количестве устройств, и сочетание размеров экрана и плотности экрана может показаться огромным. Приведенные ниже советы помогут сократить усилия, необходимые для поддержки различных устройств.
Разработка и разработка только для того, что вам нужно – Существует множество различных устройств, но некоторые из них существуют в редких конструктивных факторах, которые могут требовать значительных усилий при проектировании и разработке. Панель мониторинга " размер и плотность экрана " — это страница, предоставляемая Google, которая предоставляет данные о декомпозиции размера экрана и матрицы плотности экрана. Эта декомпозиция позволяет получить представление о том, как выполнять разработку на экранах с поддержкой.
Использование DP, а не пикселей в пикселях, становится проблематичным при изменении плотности экрана. Не жестко кодировать значения пикселей. Старайтесь не использовать пикселов в качестве точки распространения (не зависящих от плотности).
Избегайте абсолутелайаут везде, где это возможно – , не рекомендуется на уровне API 3 (Android 1,5) и приведет к нестабильнымм макетов. Его не следует использовать. Вместо этого попробуйте использовать более гибкие графические элементы макета, такие как элемент LinearLayout, RelativeLayoutили новое значение GridLayout.
Выбрать одну ориентацию макета по умолчанию – Например, вместо использования альтернативных ресурсов Layout-Land и Layout-Port, разместите ресурсы для альбомной ориентации в макете, а ресурсы для книжной ориентации — на порт макета.
Использовать лайаутпарамс для высоты и ширины . при определении элементов пользовательского интерфейса в XML-файле макета приложение Android, использующее значения wrap_content и fill_parent , будет иметь более успешный вид на различных устройствах, чем использование пикселей или единиц распределения плотности. Эти значения измерений приводят к тому, что Android масштабирует ресурсы растрового изображения соответствующим образом. По той же причине единицы, не зависящие от плотности, лучше зарезервированы для при указании полей и дополнений элементов пользовательского интерфейса.
Тестирование нескольких экранов
Приложение Android должно быть протестировано для всех конфигураций, которые будут поддерживаться. Оптимальные устройства следует тестировать на самих устройствах, но во многих случаях это невозможно или практично. В этом случае будет полезно использовать программу установки эмулятора и виртуальных устройств Android для каждой конфигурации устройства.
Пакет SDK для Android предоставляет некоторые обложки эмулятора, которые могут использоваться для создания AVD, которые будут реплицировать размер, плотность и разрешение множества устройств. Многие поставщики оборудования также предоставляют обложки для своих устройств.
Другой вариант — использовать службы службы тестирования третьих сторон. Эти службы будут принимать APK, запускать их на различных устройствах, а затем оставлять отзывы о том, как работает приложение.
На странице фрагмента на официальном сайте приводятся куски кода приложения. Это приложение отображает список заголовков статей и содержимое выбранной статьи, а его вид зависит от ориентации экрана. В горизонтальной ориентации, оно отображает и заголовки и содержимое(два фрагмента в одном Activity). В вертикальной ориентации заголовки и содержимое отображаются на разных экранах (два фрагмента разделены по двум Activity).
Пример достаточно полезен, и я решил, что имеет смысл разобрать его детально. Я немного поменяю и сокращу код, но общий смысл конструкции останется неизменным. Также, думаю, будет полезным, если мы создадим приложение так, что оно будет запускаться на версиях более ранних, чем третья. Ну и в довесок сделаем так, чтобы оно работало адекватно на экранах разных размеров.
Соответственно урок состоит из трех частей.
1. Приложение, отображающее слева заголовки, а справа – содержимое
2. Добавляем учет ориентации. При вертикальной будем отображать заголовки на первом экране, а содержимое на втором.
3. Добавляем учет размера экрана. Для небольших экранов в любой ориентации будем отображать заголовки на первом экране, а содержимое на втором.
Долго думал, как назвать проект. Решил – MultipleScreen.
Project name: P1151_MultipleScreen
Build Target: Android 2.2
Application name: MultipleScreen
Package name: ru.startandroid.develop.p1151multiplescreen
Create Activity: MainActivity
Добавим строки в strings.xml:
Два массива – заголовки и содержимое.
Не забывайте, что мы используем библиотеку v4, чтобы наше приложение с фрагментами работало на старых версиях.
Создаем фрагмент, который будет отображать список заголовков
TitlesFragment.java:
Класс наследует ListFragment для удобства работы со списком.
onItemClickListener – интерфейс, который будет наследовать Activity. Подробно эту схему мы разбирали в Уроке 106. Интерфейс имеет метод itemClick, который фрагмент будет вызывать при выборе элемента списка.
В onCreate создаем адаптер с заголовками и передаем его списку.
В onAttach записываем Activity (к которому присоединен фрагмент) в listener. Разумеется, это Activity должно реализовывать интерфейс onItemClickListener.
В onListItemClick, мы через listener посылаем в Activity данные о выбранном элементе.
Т.е. этот фрагмент покажет нам заголовки и уведомит Activity о том, какой из них был выбран.
Создаем второй фрагмент, для отображения содержимого.
layout-файл details.xml:
TextView, который будет отображать содержимое.
Класс DetailsFragment.java:
Метод newInstance создает экземпляр фрагмента и записывает в его атрибуты число, которое пришло на вход методу. Это число будет содержать позицию выбранного элемента из списка заголовков.
Метод getPosition достает из аргументов позицию.
onCreateView создает View, находим в нем TextView, и помещает в этот TextView содержимое, соответствующее позиции.
Для нас тут новыми являются аргументы фрагмента. Они могут быть заданы строго до того, как фрагмент будет присоединен к какому либо Activity, т.е., обычно, сразу после создания фрагмента. Они хранятся в фрагменте даже после того, как он был пересоздан в результате, например, смены ориентации экрана. Метод setArguments позволяет записать аргументы, а getArguments – считать.
Этот фрагмент при создании читает содержимое по переданной ему позиции и выводит в TextView.
Настраиваем Activity. layout-файл main.xml:
Слева будет TitlesFragment с заголовками, а в правой части будем помещать DetailsFragment в контейнер FrameLayout.
MainActivity.java:
Activity наследует интерфейс onItemClickListener, чтобы получать оповещения о выбранных элементах от фрагмента со списком заголовков. Поле position будет хранить последний выбранный элемент. Это поле сохраняем (onSaveInstanceState) и читаем (savedInstanceState в onCreate) при пересоздании Activity.
В onCreate вызываем метод, который покажет последнюю выбранную запись.
Метод showDetails получает на вход позицию, ищет DetailsFragment. Если не находит или находит но, отображающий данные по другой позиции, то создает фрагмент заново, передает ему нужную позицию и размещает в контейнер.
itemClick – метод, вызываемый из фрагмента со списком заголовков. В нем мы получаем позицию выбранного элемента в списке. Пишем ее в поле position и вызываем showDetails, который отобразит нужные данные на экране.
Все сохраняем, запускаем приложение.
Выберем какой-либо пункт
все работает, как и должно.
Теперь добавим учет ориентации экрана. В вертикальной ориентации MainActivity будет отображать только заголовки. Фрагмент с содержимым вынесем в отдельное DetailsActivity
DetailsActivity.java:
Код из рубрики: «все слова вроде знакомые, а че сказать хотел - непонятно». Давайте разбираться.
Представим ситуацию. Мы поворачиваем планшет вертикально, у нас отобразятся только заголовки. Мы нажимаем на какой-либо заголовок и переходим на DetailsActivity, которое покажет нам содержимое (средствами DetailsFragment, разумеется). Т.е. мы имеем вертикальную ориентацию и видим содержимое. Теперь поворачиваем планшет горизонтально. Что будет? DetailsActivity отобразится во весь горизонтальный экран и покажет содержимое. Но наша концепция гласит, что в горизонтальной ориентации приложение должно показывать и содержимое и заголовки, ширина экрана ведь позволяет это сделать. А, значит, нам надо вернуться в MainActivity.
Смотрим первый фрагмент кода. Приложение определяет, что ориентация горизонтальная и в этом случае просто закрывает Activity. И т.к. это DetailsActivity у нас будет вызвано из MainActivity, то после finish мы попадаем в MainActivity и видим то, что нужно – и заголовки, и содержимое. Причем MainActivity хранит номер выбранного заголовка (независимо от ориентации) и содержимое отобразится то же самое, что было в DetailsActivity.
Смотрим второй фрагмент. Мы проверяем, что savedInstanceState == null – это означает, что Activity создается первый раз, а не пересоздается после смены ориентации экрана. Далее мы создаем фрагмент DetailsFragment, используя позицию из интента, и помещаем его в Activity.
Почему создаем фрагмент только при создании Activity и при пересоздании - нет? Потому что система сама умеет пересоздавать существующие фрагменты при поворотах экрана, сохраняя при этом аргументы фрагмента. И нам совершенно незачем в данном случае пересоздавать фрагмент самим.
Причем тут надо понимать, что система будет создавать фрагмент вовсе не через метод newInstance. Она просто не знает такой метод. Система использует конструктор. И мы ничего не можем передать в этот конструктор, чтобы повлиять на поведение или содержимое фрагмента. Именно в таких случаях выручают аргументы. Система сохраняет аргументы фрагмента при его пересоздании. И при каждом пересоздании наш фрагмент будет знать, какое содержимое он должен отобразить, т.к. использует аргументы при создании экрана в методе onCreateView.
Не забудьте прописать Activity в манифесте.
Создадим папку res/layout-land и скопируем туда основной layout - res/layout/main.xml. Т.е. при горизонтальной ориентации у нас все останется, как есть.
А res/layout/main.xml поменяем следующим образом:
Мы удалили контейнер для содержимого, оставили только заголовки. Такой экран мы получим в вертикальной ориентации.
Меняем MainActivity.java:
Изменений немного. Добавляется поле withDetails, которое будет сообщать нам: показывает Activity заголовки с содержимым или без. В нашем случае это будет совпадать соответственно с горизонтальной и вертикальной ориентацией.
В onCreate мы задаем значение withDetails с помощью проверки наличия контейнера для фрагмента с содержимым. Если у нас должно отображаться содержимое, то вызываем метод showDetails и передаем ему позицию. Если содержимое не должно отображаться, то ничего не делаем, показываем только заголовки.
В методе showDetails мы смотрим withDetails. Если содержимое должно быть показано здесь же, то работает старый алгоритм, мы создаем фрагмент. Если же содержимое должно быть показано в отдельном Activity, то вызываем DetailsActivity и передаем ему позицию.
Все сохраняем, запускаем приложение.
видим только заголовки
видим содержимое в новом Activity
видим содержимое и заголовки
Осталось подстроить работу приложения под маленькие экраны. Напомню, что на мелких экранах мы при любой ориентации будем разделять заголовки и содержимое по разным Activity. Размер экрана можно определять по-разному. Я буду считать большими экраны large и xlarge. Для этих экранов логика остается текущая, для остальных немного изменим.
Ориентация экрана бывает горизонтальная (land) и вертикальная (port). Экраны мы будем различать: мелкие, large и xlarge. Итого у нас получается 6 комбинаций экранов.
И у нас уже есть два варианта файла main.xml – "заголовки с содержимым" и "только заголовки".
Надо сопоставить комбинации и варианты.
Вариант "заголовки с содержимым" будем использовать в комбинациях 5,6 (большие экраны в горизонтальной ориентации)
Вариант "только заголовки" подходит к комбинациям 1,2,3,4 (мелкие экраны в любой ориентации и большие экраны в вертикальной ориентации).
Создаем layout-папки под эти комбинации, и помещаем в них варианты экранов.
Папка res/layout-large-land. Это комбинация 5. Сюда помещаем вариант main.xml, который "заголовки с содержимым".
Папка res/layout-xlarge-land. Это комбинация 6. Сюда помещаем вариант main.xml, который "заголовки с содержимым".
Папка res/layout. Это все остальные комбинации (1,2,3,4). Сюда помещаем вариант main.xml, который "только заголовки".
Т.е. в итоге получается, что мы в папки layout-large-land и layout-xlarge-land копируем файл из layout-land, и удаляем папку layout-land. Папку layout не трогаем, там все ок.
Осталось немного изменить DetailsActivity.java:
Метод isLarge определяет, большой экран или нет. Если раньше мы в горизонтальной ориентации сразу закрывали это Activity, то теперь будем делать это только для больших экранов. А на остальных содержимое будет отображаться в горизонтальной ориентации.
Все сохраняем и запускаем приложение.
Скрины с планшета приводить не буду. Они полностью повторят предыдущие.
А на смартфоне с маленьким экраном будет так:
Жмем назад и попадаем к заголовкам
Немаленький такой материал получился. Но, вроде, все рассказал, чего хотел.
На всякий случай напоминаю, что архитектура решения не моя. Я разбирал пример, который немного поменял. Я перенес логику из фрагмента заголовков в главное Activity и убрал использование режима выбора и выделение элементов списка. Зато добавил работу с квалификаторами, которые позволили нам менять поведение приложения в зависимости от размера и ориентации экрана.
Если остались непонятные моменты – велкам на форум, будем решать.
На следующем уроке:
- меняем поведение Activity в Task
- в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
- ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
- новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Читайте также: