Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Вступление
Узнать ориентацию программно
Кручу-верчу, запутать хочу!
Установить ориентацию программно и через манифест
Запрет на создание новой активности
Исчезающий текст
Проверка на существование
Когда создавались первые портативные устройства - КПК и смартфоны, то за основу бралась настольная операционная система и допиливалась под мобильное устройство. Лишние функции удалялись, а некоторые функции добавлялись. Но при этом как-то совсем упустили из виду, что в отличие от громоздких мониторов и экранов ноутбуков, карманные устройства можно вращать в руках. Первые устройства не умели менять ориентацию экрана. Некоторые программисты самостоятельно стали создавать программы, которые умели переключаться в разные режимы. Затем эту возможность стали включать в настройки аппарата. Позже аппараты научились самостоятельно определять ориентацию экрана.
Всего существует два режима - портретный и альбомный. На большинстве телефонов используется по умолчанию портретный режим (как на паспорте). Альбомный режим знаком нам по обычным мониторам.
Рассмотрим следующий случай. Предположим, у нас в приложении имеется одно текстовое поле и шесть кнопок. Вроде всё нормально.

Но стоит нам повернуть устройство на 90 градусов, как сразу обнаруживаются проблемы. Пятая кнопка видна частично, а шестая вообще оказалась за пределами видимости. Непорядок!

Чтобы избежать такой проблемы, необходимо как-то по другому скомпоновать кнопки. Например, расположить их не подряд друг за другом, а разбить на пары. Воспользуемся контейнером TableLayout. С его помощью мы можем разбить кнопки на две колонки и поместить их в три ряда.
Для этой операции нам понадобится сделать несколько важных шагов. Сначала нужно создать новую подпапку в папке res. Выделяем папку res, вызываем из него контекстное меню и последовательно выбираем команды New | Android resource directory. В диалоговом окне из выпадающего списка Resource type: выбираем layout. В списке Available qualifiers: находим элемент Orientation и переносим его в правую часть Chosen qualifiers: с помощью кнопки с двумя стрелками. По умолчанию у вас появится имя папки layout-port в первой строке Directory Name:. Но нам нужен альбомный вариант, поэтому в выпадающем списке Screen orientation выбираем Landscape. Теперь название папки будет layout-land.

Можно обойтись без помощи мастера, создав папку сразу через меню New | Directory. Этот способ годится для опытных разработчиков, которые знают, как следует назвать папку. Важно запомнить, что имя даётся не произвольно, а именно в таком виде layout-land. По суффиксу -land система понимает, что речь идёт о новом режиме. Теперь нам осталось создать в созданной папке новый XML-файл activity_main.xml. Вызываем контекстное меню у папки layout-land и выбираем команды New | Layout Resource File. В диалоговом окне присваиваем имя activity_main.xml, которое должно совпадать с именем существующего файла. Во втором поле вводим LinearLayout, по мере ввода появится подсказка, облегчающая выбор.

Откроем созданный файл и модифицируем его следующим образом.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_gravity="center"
android:paddingLeft="20dp"
android:paddingRight="20dp">
<EditText
android:layout_height="wrap_content"
android:id="@+id/editText"
android:layout_width="match_parent"/>
<TableLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:stretchColumns="*">
<TableRow>
<Button
android:id="@+id/button1"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Первая кнопка"/>
<Button
android:id="@+id/button2"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Вторая кнопка"/>
</TableRow>
<TableRow>
<Button
android:id="@+id/button3"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Третья кнопка"/>
<Button
android:id="@+id/button4"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Четвёртая кнопка"/>
</TableRow>
<TableRow>
<Button
android:id="@+id/button5"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Пятая кнопка"/>
<Button
android:id="@+id/button6"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Шестая кнопка"/>
</TableRow>
</TableLayout>
</LinearLayout>
</LinearLayout>
Запускаем приложение и проверяем. Отлично, теперь видны все кнопки. Поздравляю, вы гений!

Когда вы создаёте альтернативную разметку, то не забывайте включать все компоненты, к которым будете обращаться программно, иначе получите ошибку. Допустим, вы забыли добавить шестую кнопку. В портретном режиме программа будет работать, а когда пользователь перевернёт экран, то активность будет инициализировать все компоненты для работы, а кнопки-то и нет. Крах приложения и минусы в отзывах.
Чтобы из кода узнать текущую ориентацию, можно создать следующую функцию:
// Kotlin
private fun getScreenOrientation(): String {
return when (resources.configuration.orientation) {
Configuration.ORIENTATION_PORTRAIT -> "Портретная ориентация"
Configuration.ORIENTATION_LANDSCAPE -> "Альбомная ориентация"
else -> ""
}
}
// Java
private String getScreenOrientation(){
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
return "Портретная ориентация";
else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
return "Альбомная ориентация";
else
return "";
}
Вызовите данную функцию из нужного места, например, при щелчке кнопки и узнайте текущую ориентацию. В примере использовались две распространённые системные константы для ориентации. Есть ещё константа ORIENTATION_SQUARE (квадратный экран). Но я таких телефонов не встречал.
Можно также вычислить ширину и высоту экрана, если высота больше ширины, то устройство в