我希望平板电脑能够显示肖像和景观(sw600dp或更大),但手机仅限于肖像。我找不到任何有条件地选择方向的方法。有什么建议吗?
当前回答
根据Ginny的回答,我认为最可靠的方法如下:
如本文所述,在资源sw600dp中放入一个布尔值。它必须有前缀sw,否则它将无法正常工作:
在res / values-sw600dp / dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
</resources>
在res /价值/ 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);
}
}
和一个base activity来扩展你想要的行为:
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
android:name=".login.LoginActivity"
android:configChanges="orientation|screenSize">
</activity>
其他回答
以下是我的做法(灵感来自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;
}
and:(如果你不重写这个方法,应用程序将在改变方向时调用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
}
在每个Activity的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
}
我唯一不明白的是如何让应用程序改变布局文件时,从横向到纵向或反之亦然。我假设答案是做类似于上面的链接,但我不能让它为我工作-它删除了我所有的数据。但如果你有一个足够简单的应用,你有相同的纵向和横向布局文件,这应该是可行的。
不幸的是,使用setRequestedOrientation(…)方法会导致活动重新启动,所以即使你在onCreate方法中调用这个,它也会经历活动生命周期,然后它会在请求的方向上重新创建相同的活动。所以在@Brian Christensen的回答中,你应该考虑到活动代码可能会被调用两次,这可能会产生不良影响(不仅是视觉上,而且在网络请求、分析等方面也会产生不良影响)。
此外,在清单中设置configChanges属性在我看来是一个很大的权衡,这可能会花费大量的重构成本。Android开发者不建议改变这个属性。
最后,尝试以不同的方式设置screenOrientation(以避免重新启动问题)是不可能的,静态不可能,因为静态manifest不能被改变,编程上只可能在已经启动的活动中调用该方法。
总结:在我看来,@Brian Christensen的建议是最好的权衡,但要注意重新启动活动的问题。
根据Ginny的回答,我认为最可靠的方法如下:
如本文所述,在资源sw600dp中放入一个布尔值。它必须有前缀sw,否则它将无法正常工作:
在res / values-sw600dp / dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="isTablet">true</bool>
</resources>
在res /价值/ 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);
}
}
和一个base activity来扩展你想要的行为:
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
android:name=".login.LoginActivity"
android:configChanges="orientation|screenSize">
</activity>
其他的解决方案对我都不起作用。在对话和娱乐方面,我仍然有一些奇怪的方向问题。我的解决方案是扩展活动,迫使它作为肖像在manifest。
例子:
public class MainActivityPhone extends MainActivity {}
manifest.xml:
<activity
android:screenOrientation="portrait"
android:name=".MainActivityPhone"
android:theme="@style/AppTheme.NoActionBar" />
在溅屏活动中:
Intent i = null;
boolean isTablet = getResources().getBoolean(R.bool.is_tablet);
if (!isTablet)
i = new Intent(this, MainActivityPhone.class);
else
i = new Intent(this, MainActivity.class);
startActivity(i);
我在提供的解决方案中遇到了一些问题,最后这对我来说是有效的:
在AndroidManifest.xml中设置Activity的方向为“锁定”:
<activity
android:name="com.whatever.YourActivity"
android:screenOrientation="locked"
... />
在Activity中的OnCreate(…)方法中,使用以下方法:
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState: Bundle?) {
if (isTablet(resources)) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
} else if (resources.configuration.orientation != Configuration.ORIENTATION_PORTRAIT) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
super.onCreate(savedInstanceState)
}
注意,你不需要在资源中使用布尔值的hack解决方案,你可以使用DeviceProperties类中的isTablet(资源)方法,除了其他东西之外,它检查是否smallstscreenwidthdp >= 600。
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件