Android: разрешить портрет и пейзаж для планшетов, но заставить портрет на телефоне?
Я хотел бы, чтобы планшеты могли отображаться в портретной и альбомной ориентации (sw600dp или выше), но телефоны должны быть ограничены только портретом. Я не могу найти никакого способа условно выбрать ориентацию. Есть предложения?
8 ответов:
вот хороший способ, используя ресурсы и размер квалификаторы.
поместите этот ресурс 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 студия.
затем, в методе onCreate вашей деятельности вы можно сделать так:
if(getResources().getBoolean(R.bool.portrait_only)){ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); }устройства, которые имеют более 600 dp в направлении наименьшей ширины, или x-large на устройствах pre-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) фильтр в навигаторе.
щелкните правой кнопкой мыши . Выбирай новая > Каталог Ресурсов Android.
выберите Наименьшая Ширина Экрана, а затем нажать >>.
тип
600для наименьшей ширины экрана. Имя каталога будет создано автоматически. Скажи хорошо.щелкните правой кнопкой мыши на вновь созданном . Выбирай новая > значения файла ресурсов. Типа
boolsимя.значения-большие
добавлять
values-largeкаталог необходим только в том случае, если вы поддерживаете pre Android 3.2 (уровень API 13). В противном случае вы можете пропустить этот шаг. Элемент соответствуетvalues-sw600dp. (values-xlargeсоответствуетvalues-sw720dp.)создать выполните те же шаги, что и выше, но в этом случае выберите в размере а не самый маленький экран Ширина. Выберите большой. Имя каталога будет создано автоматически.
щелкните правой кнопкой мыши каталог, как и раньше, чтобы создать .
Ну, это немного поздно, но вот это только XML но взломать решение, которое не воссоздает деятельность как
setRequestedOrientationЕсли нужно изменить ориентацию:
после Джинни, Я думаю, что самый надежный способ сделать это следующим образом:
как рассказали здесь, поместите логическое значение в ресурсы 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"для каждогоActivityв вашем AndroidManifest.XML-код:<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; -)Если вы хотите сделать наоборот, вы должны изменить код на ландшафтный (но я думаю, что это ясно, как это сделать).
к сожалению, используя метод setRequestedOrientation(...) приведет к перезапуску действия, поэтому даже если вы вызовете это в методе onCreate, он пройдет через жизненный цикл действия, а затем воссоздаст то же самое действие в запрошенной ориентации. Поэтому в ответе @Brian Christensen вы должны учитывать, что код активности может быть вызван дважды, это может иметь плохие последствия (не только визуальные, но и сетевые запросы, аналитика, так далее.).
кроме того, чтобы установить атрибут configChanges в манифесте, на мой взгляд, большой компромисс, который может потребовать больших затрат на рефакторинг. разработчики Android не рекомендуют изменять этот атрибут.
наконец, попытка установить ориентацию экрана как-то иначе (чтобы избежать проблемы перезапуска) невозможна, статически невозможна из-за статического манифеста, который не может быть изменен, программно можно только вызвать это метод в уже начатом действии.
резюме: на мой взгляд, предложение @Brian Christensen является лучшим компромиссом, но имейте в виду проблему перезапуска активности.




Comments