Классы размеров окон

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

Классы размера окна определяют доступную вашему приложению область отображения: компактную , среднюю , расширенную , большую или очень большую . Доступная ширина и высота классифицируются отдельно, поэтому в любой момент времени у вашего приложения есть два класса размера окна: один для ширины, другой для высоты. Доступная ширина обычно важнее доступной высоты из-за повсеместной вертикальной прокрутки, поэтому класс размера окна «Ширина», вероятно, более релевантен пользовательскому интерфейсу вашего приложения.

Рисунок 1. Представления классов размеров окон по ширине.
Рисунок 2. Представления классов размеров окон по высоте.

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

Размерный класс Точка останова Представление устройства
Компактная ширина ширина < 600dp 99,96% телефонов в портретном режиме
Средняя ширина 600dp ≤ ширина < 840dp 93,73% планшетов в портретном режиме,

самые большие развернутые внутренние дисплеи в портретном положении

Расширенная ширина 840dp ≤ ширина < 1200dp 97,22% планшетов в альбомной ориентации,

большинство больших внутренних дисплеев в развернутом виде в альбомной ориентации имеют ширину не менее

Большая ширина 1200dp ≤ ширина < 1600dp Большие планшетные дисплеи
Очень большая ширина ширина ≥ 1600dp Настольные дисплеи
Компактная высота высота < 480dp 99,78% телефонов в горизонтальной ориентации
Средний рост 480dp ≤ высота < 900dp 96,56% планшетов в альбомной ориентации,

97,59% телефонов в портретном режиме

Увеличенная высота высота ≥ 900dp 94,25% планшетов в портретном режиме

Хотя визуализация классов размеров в виде физических устройств может быть полезной, классы размеров окон явно не определяются размером экрана устройства. Классы размеров окон не предназначены для логики типа isTablet . Вместо этого классы размеров окон определяются размером окна, доступным вашему приложению, независимо от типа устройства, на котором оно запущено, что имеет два важных следствия:

  • Физические устройства не гарантируют определённый класс размера окна. Пространство экрана, доступное вашему приложению, может отличаться от размера экрана устройства по многим причинам. На мобильных устройствах режим разделённого экрана может разделить экран между двумя приложениями. В ChromeOS приложения Android могут быть представлены в окнах, подобных окнам настольных компьютеров, размер которых можно произвольно изменять. Складные устройства могут иметь два экрана разного размера, к которым можно получать доступ по отдельности, складывая или раскладывая устройство.

  • Класс размера окна может меняться на протяжении всего жизненного цикла вашего приложения. Во время работы приложения изменение ориентации устройства, многозадачность, а также сворачивание/разворачивание могут изменить объём доступного экранного пространства. Поэтому класс размера окна является динамическим, и пользовательский интерфейс вашего приложения должен адаптироваться соответствующим образом.

Классы размеров окон соответствуют контрольным точкам «компактный», «средний» и «расширенный» в руководстве по компоновке Material Design . Используйте классы размеров окон для принятия высокоуровневых решений по компоновке приложения, например, для определения необходимости использования определённого канонического макета для использования дополнительного пространства на экране.

Вы можете вычислить текущий WindowSizeClass с помощью функции WindowSizeClass#compute() предоставляемой библиотекой Jetpack WindowManager . В следующем примере показано, как вычислить класс размера окна и получать обновления при каждом изменении класса размера окна:

Котлин

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        val container: ViewGroup = binding.container

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(object : View(this) {
            override fun onConfigurationChanged(newConfig: Configuration?) {
                super.onConfigurationChanged(newConfig)
                computeWindowSizeClasses()
            }
        })

        computeWindowSizeClasses()
    }

    private fun computeWindowSizeClasses() {
        val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)
        val width = metrics.bounds.width()
        val height = metrics.bounds.height()
        val density = resources.displayMetrics.density
        val windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        val widthWindowSizeClass = windowSizeClass.windowWidthSizeClass
        // COMPACT, MEDIUM, or EXPANDED
        val heightWindowSizeClass = windowSizeClass.windowHeightSizeClass

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

Ява

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        ViewGroup container = binding.container;

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(new View(this) {
            @Override
            protected void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
                computeWindowSizeClasses();
            }
        });

        computeWindowSizeClasses();
    }

    private void computeWindowSizeClasses() {
        WindowMetrics metrics = WindowMetricsCalculator.getOrCreate()
                .computeCurrentWindowMetrics(this);

        int width = metrics.getBounds().width
        int height = metrics.getBounds().height()
        float density = getResources().getDisplayMetrics().density;
        WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        WindowWidthSizeClass widthWindowSizeClass = windowSizeClass.getWindowWidthSizeClass()
        // COMPACT, MEDIUM, or EXPANDED
        WindowHeightSizeClass heightWindowSizeClass = windowSizeClass.getWindowHeightSizeClass()

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

Тестовые классы размеров окон

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

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

Следующие шаги

Дополнительную информацию об использовании классов размеров окна для создания адаптивных макетов см. в следующих разделах:

Чтобы узнать больше о том, что делает приложение превосходным на всех устройствах и размерах экрана, см.: