Заставить Android-действие всегда использовать альбомный режим


145

Я использую программу просмотра Android VNC на своем HTC G1 . Но по какой-то причине это приложение всегда находится в альбомном режиме, несмотря на то, что мой G1 находится в портретном режиме. Поскольку программа просмотра Android VNC имеет открытый исходный код, я хотел бы знать, как можно жестко запрограммировать действие, чтобы оно было «ландшафтным». Я хотел бы изменить его, чтобы уважать ориентацию телефона.

Ответы:


189

Глядя на AndroidManifest.xml ( ссылка ) в строке 9:

<activity android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden" android:name="VncCanvasActivity">

Эта строка указывает screenOrientationкак альбомную, но автор идет дальше, отменяя любые изменения ориентации экрана с помощью configChanges="orientation|keyboardHidden". Это указывает на переопределенную функцию в VncCanvasActivity.java.

Если вы посмотрите на VncCanvasActivity, в строке 109 будет переопределенная функция:

@Override
public void onConfigurationChanged(Configuration newConfig) {
  // ignore orientation/keyboard change
  super.onConfigurationChanged(newConfig);
}

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


Если вы хотите изменить это, вы можете вернуться к файлу AndroidManifest.xml, показанному выше, и изменить строку на:

<activity android:screenOrientation="sensor" android:name="VncCanvasActivity">

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

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


3
Зачем именно configChangesнужен атрибут? Кажется, он работает на моем телефоне без клавиатуры и без него ... В каких ситуациях ориентация изменится на портретную, если у вас есть, screenOrientation="landscape"но опустить configChanges?
Timmmm


как заставить встроенное действие, такое как библиотека выбора системного изображения, только в альбомной или только в портретной ориентации?
LiangWang

119

Вы также можете установить те же данные в своем Java-коде.

myActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Другие значения ActivityInfo позволят вам вернуть его к управляемому датчику или заблокированному портрету. Лично мне нравится устанавливать для него что-то в манифесте, как предлагается в другом ответе на этот вопрос, а затем изменять его позже, используя указанный выше вызов в Android SDK, если в этом есть необходимость.


@ Егор Не всегда. Из документов Android:If the activity is currently in the foreground or otherwise impacting the screen orientation, the screen will immediately be changed (possibly causing the activity to be restarted)
Чайтанья

40

В моем OnCreate(Bundle)я обычно делаю следующее:

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

2
метод manifest в других ответах, похоже, не работал, но @anwarma yours
Anup

31

Вы можете указать направление деятельности в манифесте. Смотрите здесь .

<activity android:allowTaskReparenting=["true" | "false"]
...
          android:screenOrientation=["unspecified" | "user" | "behind" |
                                     "landscape" | "portrait" |
                                     "sensor" | "nosensor"]
...
                                       "adjustResize", "adjustPan"] >  

25

В манифесте:

<activity  android:name=".YourActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize">

В вашей деятельности:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.your_activity_layout);

11

Ниже приведен код, который я использовал для отображения всей активности в ландшафтном режиме:

<activity android:screenOrientation="landscape"
          android:configChanges="orientation|keyboardHidden"
          android:name="abcActivty"/>

2
«Ориентация». Если ваше приложение нацелено на уровень API 13 или выше, вы также должны объявить «screenSize»
Мина Фаузи,

7

Быстрое и простое решение для файла AndroidManifest.xml: добавьте следующее для каждого действия, которое вы хотите принудительно переключить в альбомный режим:

android:screenOrientation="landscape"

5

Это работает для Xamarin.Android. В OnCreate ()

RequestedOrientation = Android.Content.PM.ScreenOrientation.Landscape;

4

Это оно!! Долго ждал этого исправления.

У меня старая проблема Android с двойным запуском действия, которое требовало (программно) ландшафтного режима: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)

Теперь Android при запуске делает альбомный режим.


3

Арслан, почему ты хочешь принудительно ориентировать программно, хотя способ уже есть в манифесте <activity android:name=".youractivityName" android:screenOrientation="portrait" />


Я не спрашивающий, но, может быть, он хочет принудительно принудительно, потому что он хочет заставить его в определенное время?
Хамза Малик

1

Делать это в коде - это неправильно ИМО, и тем более, если вы поместите его в onCreate. Сделайте это в манифесте, и «система» узнает ориентацию с момента запуска приложения. И этот тип мета или «руководства» верхнего уровня ДОЛЖЕН быть в манифесте. Если вы хотите доказать это себе, установите перерыв в Activity onCreate. Если вы сделаете это в коде, он будет вызываться дважды: он запускается в портретном режиме, затем переключается в альбомный. Этого не произойдет, если вы сделаете это в манифесте.


1
Я не согласен. Я всегда предпочитаю делать что-либо в коде, а не через манифест. Основываясь на принципе единой ответственности, манифест должен касаться только свойств, разрешений и привязок API на уровне приложения. На самом деле я не согласен с тем, что тег <activity> вообще присутствует в манифесте приложения, и поэтому я никогда не помещал его туда (и он отлично работает). То, как представлена ​​деятельность, очевидно, является проблемой презентации. Ваша деятельность должна нести единоличную ответственность за то, как она представлена, поэтому я обычно помещаю всю логику представления в код представления / действия.
ComeIn

1

Добавить в действие следующие строки

Вам нужно войти в каждое действие

для пейзажа

android:screenOrientation="landscape"
tools:ignore="LockedOrientationActivity"

для портрета

android:screenOrientation="portrait"
tools:ignore="LockedOrientationActivity"

Вот пример MainActivity

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="org.thcb.app">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity"
            android:screenOrientation="landscape"
            tools:ignore="LockedOrientationActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".MainActivity2"
            android:screenOrientation="portrait"
            tools:ignore="LockedOrientationActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

0

Для Android 4.0 (Ice Cream Sandwich) и более поздних версий мне нужно было добавить их, помимо landscapeзначения.

android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"

Использование только keyboardHidden|orientationвсе равно приведет к утечке памяти и восстановлению моих действий при нажатии кнопки питания.


Предупреждение о плохой практике! Это не имеет ничего общего с принудительной активностью в ландшафтном режиме. Вам всегда необходимо реализовать сохранение и воссоздание состояния вашей активности. Это базовые знания о разработке под Android. Не решайте эту проблему с помощью этого хакерского исправления. Операция всегда может быть закрыта системой, если ей требуется больше памяти.
Roel

@Roel, ну, это единственный способ предотвратить поворот активности обратно в портрет, когда, например, вы поворачиваете устройство. Это предотвращает влияние этих изменений конфигурации на активность.
Peterdk

Извините за немного сварливое сообщение, но я тестировал его, и у меня нет всех этих значений для ландшафтного режима. Когда вы добавляете все эти значения, это означает, что вы сами обрабатываете изменения в onConfigurationChanged () вместо того, чтобы действие просто перезапускалось (и вы должны реализовать это!), Но если вы принудительно используете landchape, вращения не произойдет.
Roel

Привет, некоторые из них могут не понадобиться, но пропуск всех из них приведет к странным проблемам с вращением. Сейчас я не могу тестировать, но когда я разрабатывал приложение, которое должно было постоянно работать в горизонтальном режиме, одного использования orientation|screensizeбыло недостаточно во всех случаях. Он автоматически вернется в портретное положение.
Peterdk

Эти изменения конфигурации также используются в Google Mobile Ads и других рекламных SDK. Вот откуда я их тогда взял.
Peterdk

0

Используйте ActivityInfo (android.content.pm.ActivityInfo) в своем методе onCreate перед вызовом метода setLayout, подобного этому

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.