Android:允许肖像和风景的平板电脑,但强迫在手机上的肖像?

我希望平板电脑能够以纵向和横向显示(sw600dp或更高),但手机仅限于纵向显示。 我找不到任何有条件地select方向的方法。 有什么build议么?

这是一个使用资源和大小限定符的好方法。

把这个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 dp的设备,或基于Android 3.2平板设备(基本上为平板电脑)上的x-large,将基于传感器和用户locking旋转等行为performance正常。 其他一切(手机,非常)将只是肖像。

您可以尝试这种方式首先获得设备的屏幕大小

 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-sw600dpres/values-large目录与其bools.xml文件一起添加。

价值观sw600dp

首先,从项目选项卡中select导航器中的项目(而不是Android)filter。

在这里输入图像说明

然后右键点击app/src/main/res目录。 select新build > Android资源目录

select最小的屏幕宽度 ,然后按>>button。

在这里输入图像说明

input600为最小的屏幕宽度。 目录名称将自动生成。 说OK。

在这里输入图像说明

然后右键单击新创build的values-sw600dp文件。 select新build > 值资源文件 。 键bools名称。

值,大

只有在支持预安卓3.2(API级别13)的情况下,才需要添加values-large目录。 否则,你可以跳过这一步。 values-large目录对应于values-sw600dp 。 ( values-xlarge对应于values-sw720dp 。)

要创buildvalues-large目录,请按照上述步骤进行操作,但在这种情况下,请select“ 大小”而不是“最小屏幕宽度”。 select 。 目录名称将自动生成。

在这里输入图像说明

像以前一样右键单击该目录以创buildbools.xml文件。

那么,这是一个晚了点,但是,这里是一个XML-Only,但一个黑客解决scheme,不重新创build一个活动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"行添加到AndroidManifest.xml中的每个Activity

  <activity android:name=".login.LoginActivity" android:configChanges="orientation|screenSize"> </activity> 

老问题我知道。 为了在纵向模式下运行你的应用程序,即使在方向可能被交换的情况下(例如在平板电脑上),我也devise了这个function,用于在正确的方向上设置设备,而不需要知道纵向和横向function在设备上组织。

  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方法中调用此方法,它也会经历活动生命周期,然后它将以请求的方向重新创build相同的活动。 因此,在@Brian Christensen的回答中,您应该考虑活动代码可能会被调用两次,这可能会产生不良影响(不仅是可视化的,还有networking请求,分析等)。

而且,在清单中设置configChanges属性在我看来是一个很大的折衷,这可能需要大量的重构成本。 Android Devs不build议改变这个属性 。

最后,试图设置screenOrientation不同的方式(以避免重新启动问题)是不可能的,由于静态清单不可能被改变,静态的不可能的,编程方式只能在已经开始的活动中调用该方法。

总结:在我看来,@Brian Christensen的build议是最好的折衷scheme,但要注意重新开始的活动问题。