Android: разрешить портрет и пейзаж для планшетов, но заставить портрет на телефоне?

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

Solutions Collecting From Web of "Android: разрешить портрет и пейзаж для планшетов, но заставить портрет на телефоне?"

Вот хороший способ использования ресурсов и размеров .

Поместите этот ресурс bool в res / values ​​как bools.xml или что угодно (имена файлов здесь неважны):

  <?xml version="1.0" encoding="utf-8"?> <resources> <bool name="portrait_only">true</bool> </resources> 

Поместите это в res / values-sw600dp и res / values-xlarge:

  <?xml version="1.0" encoding="utf-8"?> <resources> <bool name="portrait_only">false</bool> </resources> 

Дополнительную информацию см. В этом дополнительном ответе для добавления этих каталогов и файлов в Android Studio.

Затем в методе onCreate вашей деятельности вы можете сделать следующее:

  if(getResources().getBoolean(R.bool.portrait_only)){ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } 

Устройства размером более 600 дп в наименьшем направлении ширины или x-large на устройствах до Android 3.2 (планшеты в основном) будут вести себя как обычно, на основе датчика и поворота с помощью пользователя и т . Д. Все остальное (телефоны, в значительной степени) будет только портфолио.

Вы можете попробовать таким образом, сначала получить размер экрана устройства

 if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) { Toast.makeText(this, "Large screen",Toast.LENGTH_LONG).show(); } else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) { Toast.makeText(this, "Normal sized screen" , Toast.LENGTH_LONG).show(); } else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) { Toast.makeText(this, "Small sized screen" , Toast.LENGTH_LONG).show(); } else { Toast.makeText(this, "Screen size is neither large, normal or small" , Toast.LENGTH_LONG).show(); } 

А затем установить ориентацию в соответствии с этим

 setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

Вот как я это сделал (вдохновленный http://androidblogger.blogspot.com/2011/08/orientation-for-both-phones-and-tablets.html ):

В AndroidManifest.xml для каждого действия, которое вы хотите изменить между портретом и ландшафтом (убедитесь, что вы добавили screenSize – вам это не понадобилось!) Вам не нужно устанавливать ориентацию экрана здесь. :

 android:configChanges="keyboardHidden|orientation|screenSize" 

Методы добавления в каждую активность:

 public static boolean isXLargeScreen(Context context) { return (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE; } 

И: (если вы не переопределите этот метод, приложение будет вызывать onCreate () при изменении ориентации)

 @Override public void onConfigurationChanged (Configuration newConfig) { super.onConfigurationChanged(newConfig); if (!isXLargeScreen(getApplicationContext()) ) { return; //keep in portrait mode if a phone } //I set background images for landscape and portrait here } 

В onCreate () каждой операции:

 if (!isXLargeScreen(getApplicationContext())) { //set phones to portrait; setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { //I set background images here depending on portrait or landscape orientation } 

Единственное, что я не могу понять, так это то, как заставить приложение изменять файлы макета при переключении с ландшафта на портрет или наоборот. Я предполагаю, что ответ делает что-то похожее на то, что делает ссылка выше, но я не мог заставить это работать для меня – он удалил все мои данные. Но если у вас достаточно простое приложение, у вас есть один и тот же файл макета для портрета и пейзажа, это должно сработать.

Дополнение к принятому ответу

Вы можете сделать следующие шаги в Android Studio, чтобы добавить файлы res/values-sw600dp и res/values-large с файлами bools.xml .

Значения-sw600dp

Прежде всего, на вкладке «Проект» выберите в навигаторе фильтр «Проект (а не Android)».

Введите описание изображения здесь

Затем щелкните правой кнопкой мыши каталог app/src/main/res . Выберите « Создать» > « Каталог ресурсов Android» .

Выберите « Наименьшая ширина экрана» , а затем нажмите кнопку >> .

Введите описание изображения здесь

Введите 600 для минимальной ширины экрана. Имя каталога будет автоматически сгенерировано. Скажи "ОК.

Введите описание изображения здесь

Затем щелкните правой кнопкой мыши на вновь созданных values-sw600dp . Выберите « Создать» > « Файл значений» . Введите bools для имени.

Значения-большие

Добавление каталога values-large необходимо только в том случае, если вы поддерживаете предварительный Android 3.2 (уровень API 13). В противном случае вы можете пропустить этот шаг. values-large каталог соответствует values-sw600dp . ( values-xlarge соответствуют values-sw720dp .)

Чтобы создать каталог с values-large , выполните те же действия, что и выше, но в этом случае выберите « Размер», а не «Наименьшая ширина экрана». Выберите Большой . Имя каталога будет автоматически сгенерировано.

Введите описание изображения здесь

Щелкните правой кнопкой мыши каталог по-прежнему, чтобы создать файл bools.xml .

Ну, это немного поздно, но вот XML-Only, но хакерское решение, которое не воссоздает активность как setRequestedOrientation , если нужно изменить ориентацию:

https://stackoverflow.com/a/27015879/1281930

Следуя ответу Джинни , я думаю, что самый надежный способ сделать это:

Как описано здесь , поставьте логическое значение в ресурсах sw600dp. Он должен иметь префикс sw, иначе он не будет работать должным образом:

В res / values-sw600dp / dimens.xml

 <?xml version="1.0" encoding="utf-8"?> <resources> <bool name="isTablet">true</bool> </resources> 

В res / values ​​/ dimens.xml

 <?xml version="1.0" encoding="utf-8"?> <resources> <bool name="isTablet">false</bool> </resources> 

Затем сделайте метод для извлечения этого логического значения:

 public class ViewUtils { public static boolean isTablet(Context context){ return context.getResources().getBoolean(R.bool.isTablet); } } 

И базовую деятельность, которая распространяется на действия, в которых вы хотите этого поведения:

 public abstract class BaseActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!ViewUtils.isTablet(this)) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } } 

Таким образом, каждое действие расширяет BaseActivity:

 public class LoginActivity extends BaseActivity //.... 

Важно : даже если вы расширяетесь из BaseActivity , вы должны добавить строку android:configChanges="orientation|screenSize" для каждой android:configChanges="orientation|screenSize" в вашем AndroidManifest.xml:

  <activity android:name=".login.LoginActivity" android:configChanges="orientation|screenSize"> </activity> Размер  <activity android:name=".login.LoginActivity" android:configChanges="orientation|screenSize"> </activity> 

Старый вопрос, который я знаю. Чтобы запустить приложение всегда в портретном режиме, даже если ориентация может быть или меняться и т. Д. (Например, на планшетах), я разработал эту функцию, которая используется для установки устройства в правильной ориентации без необходимости знать, как портрет и пейзаж Функции организованы на устройстве.

  private void initActivityScreenOrientPortrait() { // Avoid screen rotations (use the manifests android:screenOrientation setting) // Set this to nosensor or potrait // Set window fullscreen this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); DisplayMetrics metrics = new DisplayMetrics(); this.activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); // Test if it is VISUAL in portrait mode by simply checking it's size boolean bIsVisualPortrait = ( metrics.heightPixels >= metrics.widthPixels ); if( !bIsVisualPortrait ) { // Swap the orientation to match the VISUAL portrait mode if( this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ) { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); } } else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); } } 

Работает как шарм!

ВНИМАНИЕ. Измените this.activity активность на активность или добавьте ее в основное действие и удалите this.activity 😉

Если вы хотите сделать обратное, вы должны изменить код на пейзаж (но я думаю, что это понятно, как это сделать).