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-sw600dp
和res/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
如果必须改变方向:
根据金妮的回答 ,我认为最可靠的做法如下:
如上所述,在资源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,但要注意重新开始的活动问题。