1 page.title=Supporting Different Screen Sizes
2 parent.title=Designing for Multiple Screens
6 next.title=Supporting Different Screen Densities
7 next.link=screendensities.html
12 <!-- This is the training bar -->
16 <h2>Содержание урока</h2>
18 <li><a href="#TaskUseWrapMatchPar">Использование параметров wrap_content и match_parent</a></li>
19 <li><a href="#TaskUseRelativeLayout">Использование объекта RelativeLayout</a></li>
20 <li><a href="#TaskUseSizeQuali">Использование квалификаторов размера</a></li>
21 <li><a href="#TaskUseSWQuali">Использование квалификатора Smallest-width</a></li>
22 <li><a href="#TaskUseAliasFilters">Использование псевдонимов макетов</a></li>
23 <li><a href="#TaskUseOriQuali">Использование квалификаторов ориентации</a></li>
24 <li><a href="#TaskUse9Patch">Использование растровых изображений nine-patch</a></li>
27 <h2>Дополнительные материалы</h2>
30 <li><a href="{@docRoot}guide/practices/screens_support.html">Поддержка нескольких экранов</a></li>
35 <div class="download-box">
36 <a href="http://developer.android.com/shareables/training/NewsReader.zip" class="button">Загрузить учебное приложение</a>
37 <p class="filename">NewsReader.zip</p>
43 <p>В этом уроке описаны следующие аспекты обеспечения совместимости интерфейса с разными экранами:</p>
45 <li>обеспечение способности макета адаптироваться к размеру экрана;</li>
46 <li>выбор макета интерфейса, отвечающего конфигурации экрана;</li>
47 <li>контроль правильности применяемого макета;</li>
48 <li>использование масштабируемых растровых изображений.</li>
52 <h2 id="TaskUseWrapMatchPar">Использование параметров wrap_content и match_parent</h2>
54 <p>Чтобы создать масштабируемый макет, способный адаптироваться к разным экранам, используйте в качестве значений ширины и высоты отдельных компонентов представления параметры <code>"wrap_content"</code> и <code>"match_parent"</code>. Если используется <code>"wrap_content"</code>, для ширины или высоты представления устанавливается минимальное значение, позволяющее уместить содержание на экран, а параметр <code>"match_parent"</code> (известный как <code>"fill_parent"</code> в API до 8 уровня) служит для растягивания компонента по размеру родительского представления.</p>
56 <p>Если указать параметры <code>"wrap_content"</code> и <code>"match_parent"</code> вместо строго заданных размеров, в представлениях будет использоваться минимально необходимое место или они будут растягиваться на всю доступную длину и ширину соответственно. Например:</p>
58 {@sample development/samples/training/multiscreen/newsreader/res/layout/onepane_with_bar.xml all}
60 <p>Обратите внимание на то, что в коде учебного приложения размеры компонентов заданы с помощью параметров <code>"wrap_content"</code> и <code>"match_parent"</code>. В результате макет правильно отображается на экранах разных размеров при разных ориентациях.</p>
62 <p>Например, вот так он выглядит в вертикальной и горизонтальной ориентациях. Обратите внимание на то, как размеры компонентов автоматически адаптируются к длине и ширине:</p>
64 <img src="{@docRoot}images/training/layout-hvga.png" />
65 <p class="img-caption"><strong>Рисунок 1</strong>. Приложение News Reader при вертикальной (слева) и горизонтальной (справа) ориентации.</p>
68 <h2 id="TaskUseRelativeLayout">Использование объекта RelativeLayout</h2>
70 <p>С помощью вложенных экземпляров объекта <PH>{@link android.widget.LinearLayout}</PH> и параметров <code>"wrap_content"</code> и <code>"match_parent"</code> можно создавать достаточно сложные макеты. Однако <PH>{@link android.widget.LinearLayout}</PH> не дает возможности точно управлять взаимным расположением дочерних представлений: в <PH>{@link android.widget.LinearLayout}</PH> они просто помещаются в ряд друг за другом. Если необходимо расположить дочерние представления иным образом, используйте объект <PH>{@link android.widget.RelativeLayout}</PH>, позволяющий задать относительные позиции компонентов. Например, одно дочернее представление можно выровнять по левому краю экрана, а другое – по правому.</p>
75 <?xml version="1.0" encoding="utf-8"?>
76 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
77 android:layout_width="match_parent"
78 android:layout_height="match_parent">
80 android:id="@+id/label"
81 android:layout_width="match_parent"
82 android:layout_height="wrap_content"
83 android:text="Type here:"/>
85 android:id="@+id/entry"
86 android:layout_width="match_parent"
87 android:layout_height="wrap_content"
88 android:layout_below="@id/label"/>
90 android:id="@+id/ok"
91 android:layout_width="wrap_content"
92 android:layout_height="wrap_content"
93 android:layout_below="@id/entry"
94 android:layout_alignParentRight="true"
95 android:layout_marginLeft="10dp"
96 android:text="OK" />
98 android:layout_width="wrap_content"
99 android:layout_height="wrap_content"
100 android:layout_toLeftOf="@id/ok"
101 android:layout_alignTop="@id/ok"
102 android:text="Cancel" />
103 </RelativeLayout>
106 <p>На рис. 2 показано, как этот макет выглядит на экране QVGA.</p>
108 <img src="{@docRoot}images/training/relativelayout1.png" />
109 <p class="img-caption"><strong>Рисунок 2</strong>. Скриншот экрана QVGA (маленького размера).</p>
111 <p>На рис. 3 показано, как он выглядит на экране с большей диагональю.</p>
113 <img src="{@docRoot}images/training/relativelayout2.png" />
114 <p class="img-caption"><strong>Рисунок 3</strong>. Скриншот экрана WSVGA (большего размера).</p>
116 <p>Обратите внимание: несмотря на изменение размера компонентов их взаимное расположение остается прежним, так как оно задано объектом <PH>{@link android.widget.RelativeLayout.LayoutParams}</PH>.</p>
119 <h2 id="TaskUseSizeQuali">Использование квалификаторов размера</h2>
121 <p>Масштабируемые или относительные макеты, один из которых продемонстрирован выше, имеют свои ограничения. Хотя они позволяют создать интерфейс, способный адаптироваться к разным экранам за счет растягивания пространства внутри и вокруг компонентов, пользователю может оказаться не слишком удобно работать с таким интерфейсом. Поэтому в приложении должен использоваться не один масштабируемый макет, а несколько альтернативных вариантов для разных конфигураций экрана. Их можно создать с помощью <a href="http://developer.android.com/guide/practices/screens_support.html#qualifiers">квалификаторов конфигураций</a>, которые позволяют оперативно выбирать ресурсы, отвечающие текущим параметрам экрана (например, разные варианты макетов для экранов разных размеров).</p>
123 <p>Многие приложения отображаются на больших экранах в двухпанельном режиме, при котором список элементов расположен в одной панели, а их содержание открывается в другой. Такой режим просмотра удобен на достаточно больших экранах планшетных ПК и телевизоров, однако на экране телефона эти панели следует отображать по отдельности. Для каждого режима просмотра нужно создать отдельный файл.</p>
126 <li><code>res/layout/main.xml</code>, однопанельный макет (по умолчанию):
128 {@sample development/samples/training/multiscreen/newsreader/res/layout/onepane.xml all}
130 <li><code>res/layout-large/main.xml</code>, двухпанельный макет:
132 {@sample development/samples/training/multiscreen/newsreader/res/layout/twopanes.xml all}
136 <p>Обратите внимание, что во втором случае в названии каталога использован квалификатор <code>large</code>. Этот макет будет выбран на устройствах, экраны которых считаются большими (например, 7 дюймов и более). Первый макет (без квалификаторов) будет выбран для устройств с маленьким экраном.</p>
139 <h2 id="TaskUseSWQuali">Использование квалификатора Smallest-width</h2>
141 <p>Одной из проблем, с которой сталкивались разработчики приложений для устройств Android версий до 3.2, было слишком общее определение "большого" экрана. Это касалось устройств Dell Streak, первой модели Galaxy Tab и планшетных ПК с экраном размером 7 дюймов. Многие приложения требовалось по-разному отображать на разных устройствах (например, с 5- и 7-дюймовыми экранами), хотя они и относились к одной категории "больших" экранов. В Android версии 3.2 и более поздних доступен квалификатор Smallest-width.</p>
143 <p>Он позволяет определять экраны с заданной минимальной шириной в dp. Например, типичный планшетный ПК с экраном 7 дюймов имеет минимальную ширину 600 dp, и если вы хотите, чтобы приложение работало на нем в двухпанельном режиме (а на меньших экранах в однопанельном), используйте два макета из предыдущего раздела, но вместо квалификатора размера <code>large</code> укажите <code>sw600dp</code>. В таком случае на экранах, минимальная ширина которых составляет 600 dp, будет использоваться двухпанельный макет.</p>
146 <li><code>res/layout/main.xml</code>, однопанельный макет (по умолчанию):
148 {@sample development/samples/training/multiscreen/newsreader/res/layout/onepane.xml all}
150 <li><code>res/layout-sw600dp/main.xml</code>, двухпанельный макет:
152 {@sample development/samples/training/multiscreen/newsreader/res/layout/twopanes.xml all}
156 <p>Это означает, что на устройствах, минимальная ширина экрана которых не меньше 600 dp, будет выбран <code>layout-sw600dp/main.xml</code> (двухпанельный макет), а на экранах меньшего размера – <code>layout/main.xml</code> (однопанельный макет).</p>
158 <p>Следует учесть, что на Android-устройствах до версии 3.2 квалификатор <code>sw600dp</code> не будет работать, поэтому для них по-прежнему нужно использовать <code>large</code>. Таким образом, вам потребуется еще один файл с названием <code>res/layout-large/main.xml</code>, идентичный файлу <code>res/layout-sw600dp/main.xml</code>. В следующем разделе вы познакомитесь с методом, который позволяет избежать дублирования таких файлов макета.</p>
161 <h2 id="TaskUseAliasFilters">Использование псевдонимов макетов</h2>
163 <p>Квалификатор Smallest-width работает только на устройствах Android 3.2 или более поздних версий. Для совместимости с более ранними устройствами по-прежнему следует использовать абстрактные размеры (small, normal, large и xlarge). Например, чтобы интерфейс открывался в однопанельном режиме на телефонах и в многопанельном на планшетных ПК с 7-дюймовым экраном, телевизорах и других крупных устройствах, подготовьте следующие файлы:</p>
166 <li><code>res/layout/main.xml:</code> однопанельный макет;</li>
167 <li><code>res/layout-large:</code> многопанельный макет;</li>
168 <li><code>res/layout-sw600dp:</code> многопанельный макет.</li>
171 <p>Последние два файла идентичны: один из них предназначен для устройств Android 3.2 и новее, а второй для более старых планшетных ПК и телевизоров на платформе Android.</p>
173 <p>Чтобы не создавать дубликаты файлов и упростить процесс поддержки приложения, используйте псевдонимы. Например, можно определить следующие макеты:</p>
176 <li><code>res/layout/main.xml</code> (однопанельный макет);</li>
177 <li><code>res/layout/main_twopanes.xml</code> (двухпанельный макет).</li>
180 <p>Затем добавьте следующие два файла:</p>
183 <li><code>res/values-large/layout.xml</code>:
186 <item name="main" type="layout">@layout/main_twopanes</item>
191 <li><code>res/values-sw600dp/layout.xml</code>:
194 <item name="main" type="layout">@layout/main_twopanes</item>
201 <p>Содержание последних двух файлов одинаково, но сами по себе они не определяют макет. Они служат для того, чтобы назначить файл <PH>{@code main}</PH> в качестве псевдонима <PH>{@code main_twopanes}</PH>. Так как в них используются селекторы <code>large</code> и <code>sw600dp</code>, они применяются к планшетным ПК и телевизорам на платформе Android независимо от версии (для версий до 3.2 используется
202 <PH>{@code large}</PH>, а для более новых – <code>sw600dp</code>).</p>
205 <h2 id="TaskUseOriQuali">Использование квалификаторов ориентации</h2>
207 <p>Хотя некоторые макеты одинаково хорошо смотрятся в вертикальной и горизонтальной ориентациях, в большинстве случаев интерфейс все же приходится адаптировать. Ниже показано, как изменяется макет в приложении News Reader в зависимости от размера и ориентации экрана.</p>
210 <li><b>Маленький экран, вертикальная ориентация</b>: однопанельный вид с логотипом.</li>
211 <li><b>Маленький экран, горизонтальная ориентация</b>: однопанельный вид с логотипом.</li>
212 <li><b>Планшетный ПК с 7-дюймовым экраном, вертикальная ориентация</b>: однопанельный вид с панелью действий.</li>
213 <li><b>Планшетный ПК с 7-дюймовым экраном, горизонтальная ориентация</b>: двухпанельный вид с панелью действий.</li>
214 <li><b>Планшетный ПК с 10-дюймовым экраном, вертикальная ориентация</b>: двухпанельный вид (узкий вариант) с панелью действий.</li>
215 <li><b>Планшетный ПК с 10-дюймовым экраном, горизонтальная ориентация</b>: двухпанельный вид (широкий вариант) с панелью действий.</li>
216 <li><b>Телевизор, горизонтальная ориентация</b>: двухпанельный вид с панелью действий.</li>
219 <p>Каждый из этих макетов определен в XML-файле в каталоге <code>res/layout/</code>. Чтобы сопоставить их с определенными конфигурациями экрана, в приложении используются псевдонимы:</p>
221 <p><code>res/layout/onepane.xml:</code></p>
222 {@sample development/samples/training/multiscreen/newsreader/res/layout/onepane.xml all}
224 <p><code>res/layout/onepane_with_bar.xml:</code></p>
225 {@sample development/samples/training/multiscreen/newsreader/res/layout/onepane_with_bar.xml all}
227 <p><code>res/layout/twopanes.xml</code>:</p>
228 {@sample development/samples/training/multiscreen/newsreader/res/layout/twopanes.xml all}
230 <p><code>res/layout/twopanes_narrow.xml</code>:</p>
231 {@sample development/samples/training/multiscreen/newsreader/res/layout/twopanes_narrow.xml all}
233 <p>После того как все возможные макеты определены, остается сопоставить каждый из них с подходящей конфигурацией, используя квалификаторы конфигураций. Воспользуемся псевдонимами макетов:</p>
235 <p><code>res/values/layouts.xml</code>:</p>
236 {@sample development/samples/training/multiscreen/newsreader/res/values/layouts.xml all}
238 <p><code>res/values-sw600dp-land/layouts.xml</code>:</p>
239 {@sample development/samples/training/multiscreen/newsreader/res/values-sw600dp-land/layouts.xml
242 <p><code>res/values-sw600dp-port/layouts.xml</code>:</p>
243 {@sample development/samples/training/multiscreen/newsreader/res/values-sw600dp-port/layouts.xml
246 <p><code>res/values-large-land/layouts.xml</code>:</p>
247 {@sample development/samples/training/multiscreen/newsreader/res/values-large-land/layouts.xml all}
249 <p><code>res/values-large-port/layouts.xml</code>:</p>
250 {@sample development/samples/training/multiscreen/newsreader/res/values-large-port/layouts.xml all}
254 <h2 id="TaskUse9Patch">Использование растровых изображений nine-patch</h2>
256 <p>Чтобы интерфейс был совместим с экранами разных размеров, используемые в нем графические элементы также должны быть адаптированы соответствующим образом. Например, фон кнопки должен одинаково хорошо выглядеть независимо от ее формы.</p>
258 <p>Если использовать для компонентов, размеры которых меняются, обычные изображения, то они будут равномерно сжиматься и растягиваться, и результат будет далек от идеального. Решением являются растровые изображения формата nine-patch – специальные PNG-файлы, содержащие информацию о том, какие области можно растягивать, а какие нет.</p>
260 <p>Создавая растровые изображения для масштабируемых компонентов, обязательно используйте формат nine-patch. На рис. 4 показано обычное растровое изображение (увеличенное в 4 раза для наглядности), которое мы переведем в формат nine-patch.</p>
262 <img src="{@docRoot}images/training/button.png" />
263 <p class="img-caption"><strong>Рисунок 4</strong>. <code>button.png</code></p>
265 <p>Откройте его с помощью утилиты <ode
266 href="{@docRoot}tools/help/draw9patch.html"><code>draw9patch</code></a>, входящей в комплект разработчика (в каталоге <code>tools/</code>). Установите метки на левом и верхнем краях, чтобы ограничить области, которые можно растягивать. Можно также провести линию вдоль правого и нижнего краев, как показано на рис. 5, чтобы отметить области, в которых содержание должно быть зафиксировано.</p>
268 <img src="{@docRoot}images/training/button_with_marks.png" />
269 <p class="img-caption"><strong>Рисунок 5</strong>. <code>button.9.png</code></p>
271 <p>Обратите внимание на черные пиксели по краям. Метки у верхней и левой границ обозначают те области, которые можно растягивать, а метки у правой и нижней границ – те, куда должно быть помещено содержание.</p>
273 <p>Также обратите внимание на расширение <code>.9.png</code>. Оно должно быть задано именно в таком виде, чтобы система могла определить, что это формат nine-patch, а не обычный PNG-файл.</p>
275 <p>При применении этого фона к компоненту (с помощью <code>android:background="@drawable/button"</code>) изображение будет растянуто по размеру кнопки, как показано на рис. 6.</p>
277 <img src="{@docRoot}images/training/buttons_stretched.png" />
278 <p class="img-caption"><strong>Рисунок 6</strong>. Кнопки разных размеров с файлом фона <code>button.9.png</code> в формате nine-patch.</p>