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



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

417   8  

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) фильтр в навигаторе.

enter image description here

щелкните правой кнопкой мыши . Выбирай новая > Каталог Ресурсов Android.

выберите Наименьшая Ширина Экрана, а затем нажать >>.

enter image description here

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

enter image description here

щелкните правой кнопкой мыши на вновь созданном . Выбирай новая > значения файла ресурсов. Типа bools имя.

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

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

создать выполните те же шаги, что и выше, но в этом случае выберите в размере а не самый маленький экран Ширина. Выберите большой. Имя каталога будет создано автоматически.

enter image description here

щелкните правой кнопкой мыши каталог, как и раньше, чтобы создать .

Ну, это немного поздно, но вот это только XML но взломать решение, которое не воссоздает деятельность как 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" для каждого 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

    Ничего не найдено.