Как определить изменение ориентации в макете в Android?
Я только что реализовал функцию изменения ориентации - например, когда макет меняется с книжного на альбомный (или наоборот). Как я могу определить, когда событие изменения ориентации закончено.
OrientationEventListener
не работает. Как я могу получать уведомления о событиях изменения ориентации макета?
Ответы
Ответ 1
Используйте метод Activity onConfigurationChanged.
См. Следующий код:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
Вам также нужно отредактировать соответствующий элемент в файле манифеста, чтобы включить android: configChanges
Посмотрите код ниже:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
ПРИМЕЧАНИЕ: с Android 3.2 (уровень API 13) или выше, "размер экрана" также изменяется, когда устройство переключается между портретной и альбомной ориентацией. Таким образом, если вы хотите предотвратить перезапуск во время изменения ориентации при разработке для уровня API 13 или выше, вы должны объявить android: configChanges = "orientation | screenSize" для уровня API 13 или выше.
Надеюсь, это поможет вам...:)
Ответ 2
Для загрузки макета в папке layout-land у вас есть два отдельных макета, тогда вы должны сделать setContentView
в onConfigurationChanged
.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
setContentView(R.layout.yourxmlinlayout-land);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
setContentView(R.layout.yourxmlinlayoutfolder);
}
}
Если у вас есть только один макет, то нет необходимости делать setContentView в этом методе. просто
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
Ответ 3
Просто хотел показать вам способ сохранить весь свой пакет после onConfigurationChanged:
Создайте новый пакет сразу после вашего класса:
public class MainActivity extends Activity {
Bundle newBundy = new Bundle();
Далее, после того, как "protected void onCreate" добавьте это:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
onSaveInstanceState(newBundy);
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
onSaveInstanceState(newBundy);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBundle("newBundy", newBundy);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getBundle("newBundy");
}
Если вы добавите это, все ваши разбитые классы в MainActivity будут сохранены.
Но лучше всего добавить это в свой AndroidManifest:
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
Ответ 4
используйте этот метод
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT)
{
Toast.makeText(getActivity(),"PORTRAIT",Toast.LENGTH_LONG).show();
//add your code what you want to do when screen on PORTRAIT MODE
}
else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
{
Toast.makeText(getActivity(),"LANDSCAPE",Toast.LENGTH_LONG).show();
//add your code what you want to do when screen on LANDSCAPE MODE
}
}
И не забудьте добавить это в свой Androidmainfest.xml
android:configChanges="orientation|screenSize"
как это
<activity android:name=".MainActivity"
android:theme="@style/Theme.AppCompat.NoActionBar"
android:configChanges="orientation|screenSize">
</activity>
Ответ 5
Переопределить метод активности onConfigurationChanged
Ответ 6
Создайте экземпляр класса OrientationEventListener
и включите его.
OrientationEventListener mOrientationEventListener = new OrientationEventListener(YourActivity.this) {
@Override
public void onOrientationChanged(int orientation) {
Log.d(TAG,"orientation = " + orientation);
}
};
if (mOrientationEventListener.canDetectOrientation())
mOrientationEventListener.enable();
Ответ 7
Я просто хочу предложить другую альтернативу, которая действительно затронет некоторых из вас, как описано выше:
android:configChanges="orientation|keyboardHidden"
подразумевает, что мы явно объявляем макет для внедрения.
В случае, если мы хотим сохранить автоматический впрыск благодаря папкам layout-land и layout. Все, что вам нужно сделать, это добавить его в onCreate:
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
getSupportActionBar().hide();
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
getSupportActionBar().show();
}
Здесь мы показываем или нет панель действий в зависимости от ориентации телефона
Ответ 8
Если принятый ответ не работает, убедитесь, что вы не определили в файле манифеста:
android:screenOrientation="portrait"
Это мой случай.
Ответ 9
В случае, если это полезно для некоторых новых разработчиков, потому что это не указано выше. Просто чтобы быть очень явным:
Если вы используете onConfigurationChanged, вам нужно две вещи:
Метод onConfigurationChanged
в вашем классе деятельности
Укажите в своем манифесте, какие изменения конфигурации будут обрабатываться вашим методом onConfigurationChanged
Фрагмент манифеста в приведенных выше ответах, хотя он, без сомнения, корректен для конкретного приложения, к которому принадлежит манифест, является НЕ именно тем, что нужно добавить в манифест, чтобы вызвать метод onConfigurationChanged в ваш класс деятельности. то есть приведенная ниже запись манифеста может быть неправильной для вашего приложения.
<activity name= ".MainActivity" android:configChanges="orientation|screenSize"/>
В приведенной выше записи манифеста есть различные действия Android для android:configChanges=""
, которые могут вызвать onCreate в вашем жизненном цикле Activity.
Это очень важно - НЕ указываются в манифесте те, которые запускают ваши onCreate и . Те, которые указаны в манифесте, запускают ваш метод onConfigurationChanged
в вашем Класс деятельности.
Таким образом, вам нужно определить, какие изменения конфигурации вам нужно обрабатывать самостоятельно. Для Android Encyclopedically Challenge, как я, я использовал всплывающие подсказки в Android Studio и добавил почти все возможные варианты конфигурации. Перечисление всего этого в основном говорит, что я обработаю все, и onCreate никогда не будет вызываться из-за конфигураций.
<activity name= ".MainActivity" android:configChanges="screenLayout|touchscreen|mnc|mcc|density|uiMode|fontScale|orientation|keyboard|layoutDirection|locale|navigation|smallestScreenSize|keyboardHidden|colorMode|screenSize"/>
Теперь, очевидно, я не хочу со всем справляться, поэтому я начал устранять вышеуказанные опции по одному. Пересборка и тестирование моего приложения после каждого удаления.
Еще один важный момент: если автоматически обрабатывается только одна опция конфигурации, которая запускает ваш onCreate (он не указан в вашем манифесте выше), тогда будет казаться, что onConfigurationChanged
не работает. Вы должны поместить все соответствующие в свой манифест.
В итоге у меня было 3, которые первоначально запускали onCreate, затем я тестировал на S10+, и я все еще получал onCreate, поэтому мне пришлось снова выполнить упражнение на устранение, и мне также был нужен |screenSize
. Так что тестируйте на выбор платформ.
<activity name= ".MainActivity" android:configChanges="screenLayout|uiMode|orientation|screenSize"/>
Так что мое предложение, хотя я уверен, что кто-то может пробить дыры в этом:
Добавьте свой метод onConfigurationChanged
в свой класс активности с помощью TOAST или LOG, чтобы вы могли видеть, когда он работает.
Добавьте все возможные параметры конфигурации в манифест.
Убедитесь, что ваш метод onConfigurationChanged
работает, протестировав ваше приложение.
Удалите каждый параметр конфигурации из файла манифеста по одному, тестируя приложение после каждого.
Протестируйте как можно большее количество устройств.
Не копируйте/вставляйте мой фрагмент выше в ваш файл манифеста. Обновления Android меняют список, поэтому используйте всплывающие подсказки Android Studio, чтобы убедиться, что вы их все получили.
Надеюсь, это сэкономит кому-то время.
Мой метод onConfigurationChanged
только для информации ниже. onConfigurationChanged
вызывается в жизненном цикле после того, как доступна новая ориентация, но до пользовательского интерфейса был воссоздан. Следовательно, мой первый if
для проверки правильности ориентации работает, а затем второй вложенный if
для проверки видимости моего пользовательского интерфейса ImageView также работает правильно.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
pokerCardLarge = findViewById(R.id.pokerCardLgImageView);
if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
pokerCardLarge.setImageBitmap(image);
}
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
pokerCardLarge = findViewById(R.id.pokerCardLgImageView);
if(pokerCardLarge.getVisibility() == pokerCardLarge.VISIBLE){
Bitmap image = ((BitmapDrawable)pokerCardLarge.getDrawable()).getBitmap();
pokerCardLarge.setVisibility(pokerCardLarge.VISIBLE);
pokerCardLarge.setImageBitmap(image);
}
}
}