java 的android智能手机自动,手动切换横竖屏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 的android智能手机自动,手动切换横竖屏相关的知识,希望对你有一定的参考价值。
关于android智能手机自动,手动切换横竖屏
medium avatar
馨宇.(雅)
发表于 2014-9-22 17:29:24 浏览(12584)
假如有不对的地方,希望提出来,让我学习。
个人联系qq:1083573260 群:卓佳Droidjia 221803017
发表这个篇文章我个人觉得是有必要的,在android智能手机自动,手动切换横竖屏这一方向我所总结的,希望在后
期还能如鱼得水的熟悉该知识点。尤其是在做手机视频播放这一刚性需求---根据用户的体验感:自动加手动是用户惯
之常用的。
之前在做这个的时候,唯一能想到的方案就是重力传感器sensor,来辨别方向,是否是竖屏还是横屏,经论证这一
方案不可用。这使得我冥思苦想,于是我便想到第二总方案,那就是切换activity类。试着做了下去,结果发现,当横
屏转到竖屏时视频要获取横屏时传来的当前播放长度,导致竖屏类加载。其实也就是横屏转竖屏时activity 走了
onResume()--》oncreate()-->onConfigurationChanged()的生命周期,后来想用两个videoView来同时播放,一个关
闭声音,一个打开,相互切换。这样是不行的。写这些无非是想今后看到这篇文章的朋友不要花太多的时间去重复我上
面的路。下面来具体介绍我的解决方案:
首先我的介绍如下的东西:
一、禁止横竖屏切换
Android横竖屏切换在手机开发中比较常见,很多软件在开发过程中为了避免横竖屏切换时引发不必要的麻烦,通常禁
止掉横竖屏的切换,即通过在AndroidManifest.xml中设置activity中的android:screenOrientation属性值来实现。
该android:screenOrientation属性,他有以下几个参数:
"unspecified":默认值 由系统来判断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的显示方向.
"landscape":横屏显示(宽比高要长)
"portrait":竖屏显示(高比宽要长)
"user":用户当前首选的方向
"behind":和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)
"sensor":有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换。
"nosensor":忽略物理感应器,这样就不会随着用户旋转设备而更改了("unspecified"设置除外)。
比如下列设置
android:screenOrientation="portrait"
则无论手机如何变动,拥有这个属性的activity都将是竖屏显示。
android:screenOrientation="landscape",为横屏显示。
上述修改也可以在Java代码中通过类似如下代码来设置
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
二、横竖屏切换更改布局
如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局。可以通过以下两种方法来
切换布局:
1)在res目录下建立layout-land和layout-port目录,相应的layout文件名不变,比如main.xml。layout-land是横屏的
layout,layout-port是竖屏的layout,其他的不用管,横竖屏切换时程序为调用Activity的onCreate方法,从而加载响
应的布局。
2)假如布局资源不按照如上设置,则可以通过java代码来判断当前是横屏还是竖屏然后来加载相应的xml布局文件。因
为当屏幕变为横屏的时候,系统会重新呼叫当前Activity的onCreate方法,你可以把以下方法放在你的onCreate中来检查
当前的方向,然后可以让你的setContentView来载入不同的layout xml。
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
Log.i("info", "landscape"); // 横屏
}
else if (this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) {
Log.i("info", "portrait"); // 竖屏
}
三、通过onConfigurationChanged拦截横竖屏变换
按照二的操作,Activity每次横竖屏切换都会重新调用onPause-> onStop-> onDestory-> onCreate->onStart-
>onResume,为此涉及到内容和数据的保存和读取,否则转屏之前的内容就会消失了。很多时候这样的结果让程序繁琐
,为此Android提供了在manifest中设置android:configChanges属性,从而让Activity不延续上述的重建流程。假如用
户关心横竖屏的切换,可以在Activity或View的onConfigurationChanged(Configuration newConfig)函数中获取当前
横竖屏参数。至于其调用顺序跟touch时间的传递顺序相似,不过他没有消费事件的概念,会顺次调用到每一个
onConfigurationChanged函数。
需要注意的是,onConfigurationChanged函数中只能获得横竖屏切换后的参数,在该函数中获取不到新的Layout和控件
的尺寸位置信息,如果要处理尺寸和位置信息,必须通过消息异步或者延时调用,下面是我在项目需要横竖屏切换时需
要重新设置popupWindow位置的代码:
@Override
protected void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
//View中不用创建Handler,可直接调用post操作
// new Handler().postDelayed(new Runnable() {
// @Override
// public void run() {
// updatePopup();
// }
// }, 500);
postDelayed(new Runnable() {
@Override
public void run() {
updatePopup(); //
}
}, 500);//尝试过直接使用post操作,在updatePopup函数中也能获取正确位置
}
至于横竖屏翻转时,系统如何让窗口翻转并重新绘制,我也没有具体去细究源码,所以也不得而知,有了解的可以告知
下小弟。
当然如果要彻底禁止翻转,可以设置android:screenOrientation的属性为nosensor,如此就可以忽略重力感应带来的
麻烦了。不过在模拟器上不管用,在真机上是正确的。
这里提一个小知识,Android模拟器中,快捷键"Ctrl+F11/F12"可以实现转屏。
下面是重点:自动切换
在Activity 中的onCreate 里面加上这句
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
它的意思我用自己的理解来描述吧。就是根据当前用户手持手机方向为准,根据用户旋转手机的方向来改变横竖屏。
然后
// // 打开关闭1,关闭打开:0
Settings.System.putInt(getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 1);
动态的去设置手机系统设置的是否允许自动切换屏幕。
当活动类 activity 消亡后也就在在
onDestroy() 方法里面加上Settings.System.putInt(getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 0);
关闭 别忘记加上读取手机状态的权限
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
也许在清单里面 manifest 你得加上
android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
这样就不会重新绘制了及走 onConfigurationChanged(Configuration newConfig)这个方法
而后来看onConfigurationChanged
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { // 横屏
}else{
// 竖屏
}
我们在横屏里面设置全屏
// 全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
而在竖屏里面要多一点 --取消全屏的设置
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
// 取消全屏设置
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
在此我也来说明一点关于动态改变布局的大小的
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) framelayout
.getLayoutParams();
params.height = 400;
framelayout.setLayoutParams(params);
个人觉得这个比较靠谱点。
LinearLayout.LayoutParams params =new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
framelayout.setLayoutParams(params);
而这个有所改变差异。总之根据自己的方案办事。
手动切换屏幕这点希望大家注意。必须做到异步
// 横屏 根据用户的方向去改变屏幕的方向--在此一定要做异步延迟事件 ---islandscape 是否横竖屏
if (islandscape == false) {
setRequestedOrientation
(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
setRequestedOrientation
(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
setRequestedOrientation
(ActivityInfo.SCREEN_ORIENTATION_USER);
}
}, 5000);
为什么要这样 写因为 setRequestedOrientation
(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 根据用户当前手机方案,如果不异步就会瞬间跳回原来状态。会看到
通知栏闪动。
以上是关于java 的android智能手机自动,手动切换横竖屏的主要内容,如果未能解决你的问题,请参考以下文章
我的android平板电脑是默认横屏的,怎么才能让他变成默认竖屏
Android开发,重写了onConfigurationChanged方法。横屏切换竖屛不会重建,而竖屛切换横屏却仍会重建活动