android中Activity横竖屏切换的那些事

讲解之前需要说明的是

旋转屏幕:在系统的自动旋转屏幕开启的情况下,我们旋转屏幕 手动设置屏幕:我们自己去调用Activity的 setRequestedOrientation 方法。

设置屏幕的方向

简介

值 描述 unspecified 默认值。系统自动选择屏幕方向 behind 跟activity堆栈中的下面一个activity的方向一致 landscape 横屏方向,显示的宽比高长 portrait 竖屏方向,显示的高比宽长 sensor 由设备的物理方向传感器决定,如果用户旋转设备,这屏幕就会横竖屏切换 nosensor 忽略物理方向传感器,这样就不会随着用户旋转设备而横竖屏切换了("unspecified"设置除外) user 用户当前首选的方向 reverseLandscape API 9 以上,反向横屏 reversePortrait API 9 以上,反向竖屏 sensorLandscape API 9 以上,横屏,但是可以根据 物理方向传感器来切换正反向横屏 sensorPortrait API 9 以上,竖屏,但是可以根据 物理方向传感器来切换正反向竖屏 fullSensor API 9 以上,上下左右四个方向,由物理方向传感器决定 locked API 18 以上,锁死当前屏幕的方向

官网文档地址

第一种

我们可以在AndroidManifest 清单文件里面制定Activity的方向

<activity android:name=".view.main.MainActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity>

这样横竖屏切换的时候不会重新创建Activity

第二种

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Android:android:configChanges

如果我们不配置configuration ,当 configuration 发生变化的时候,activity会自动处理它。反之,如果我们配置了相应的 configuration,当新的 configuration 发生变化的时候,会回调 Activity 的 onConfigurationChanged() 方法。

下面我们一起来看一下几个常用的值得介绍,其他不常用的hi请自行查阅文档。官网地址:

值 描述 keyboardHidden 键盘的可访问性发生变化——例如:用户发现了硬件键盘。 orientation 屏幕方向发生变化——用户旋转了屏幕。注意:如果应用程序的目标API级别是13或更高(通过属性minSdkVersion和属性targetSdkVersion声明),你也需要声明配置项screenSize,因为这将在设备选择肖像和屏幕方向时发生改变。 screenLayout 屏幕布局发生变化——这个会导致显示不同的Activity。屏幕方向发生变化——用户旋转了屏幕。注意:如果应用程序的目标API级别是13或更高(通过属性minSdkVersion和属性targetSdkVersion声明),你也需要声明配置项screenSize,因为这将在设备选择肖像和屏幕方向时发生改变。 screenSize 当前可用屏幕大小发生变化。这代表一个当前可用大小的变化,和当前的比率相关,因此当用户选择不同的画面和图像,会发生变化。然而,如果你的程序目标API级别是12或更低,你的Activity总是会自己处理这个配置变化(这个变化不会引起Activity的重启,甚至在Android 3.2或更新的设备上)。在API级别13里加入的。

android:configChanges 常用配置

在Android 3.2以后,如果我们进行下列的配置 ,这样的话横竖屏不会重新创建Activity,但是会调用 onConfigurationChanged()方法

<activity android:name=".view.main.MainActivity" android:configChanges="keyboardHidden|orientation|screenSize" > <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> 在api 3.2 以前,我们只需这样配置即可,android:configChanges="keyboardHidden|orientation"。 <activity android:name=".view.main.MainActivity" android:configChanges="keyboardHidden|orientation" > <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity>

小结

当我们进行了上述的配置,

竖屏 》 横屏 onConfigurationChanged()方法会调用一次 横屏 》 竖屏 onConfigurationChanged()方法也会调用一次

因此我们通常可以进行相应的处理

public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { // 加入横屏要处理的代码 } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { // 加入竖屏要处理的代码 } }

如果我们同时设置了 android:configChanges="keyboardHidden|orientation|screenSize" 和 android:screenOrientation="portrait",那又会是怎样的呢?

如果我们打开系统的自动旋转屏幕,旋转屏幕,系统不会发生变化,也不会调用 Activity 的 onConfigurationChanged 方法。

当我们手动调用 setRequestedOrientation() 方法去改变屏幕的方向的时候,还是会调用 onConfigurationChanged 方法的

扩展

设置全屏模式

// 去掉ActionBar requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

在实际项目中,我们通常会固定我们应用的屏幕方向,只对一些特定的需要切换屏幕的Activity做处理,那我们如何统一设置屏幕的方向呢?

第一种方法,复制张贴,在AndroidManifest清单文件里面的每一个Activity标签增加如下标签。

<activity android:name=".MainActivity" android:screenOrientation="portrait" > </activity>

第二种方法,刚开始我直接在 AppTheme 里面 设置 android:screenOrientation,但是没有效果,刚开始我也很纳闷,后面查阅了官网文档,描述如下,才解决了疑问.

Specify the orientation an activity should be run in. If not specified, it will run in the current preferred orientation of the screen. This attribute is supported by the <activity> element.

<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <item name="android:screenOrientation">portrait</item> </style>

即这种方法不可取

第三种方法,在BaseActivity里面动态设置

public class BaseActivity extends AppCompatActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } }

同时列出这三种方法,最主要的目的不是为了告诉大家有这几种方法可以统一设置屏幕的方向,最重要的是告诉大家一种思想吧。通常在xml 文件可以设置的,在java 代码也可以设置。

利用系统的加载机制自动帮我们加载相应的布局

如果大家在资源目录res 中添加了 layout-land(横向布局文件夹) 和 layout-port (竖想布局文件夹),重启Activity模式的横竖屏切换,

可能有人会有这样的疑问,当我们设置了Activity的方向为竖屏或者横屏的时候,旋转屏幕并不会重新调用Activity的各个生命周期,那我们要怎样检测呢?

其实很简单,那就是利用我们的传感器,然后根据旋转的方向做相应的处理

//注册重力感应器 屏幕旋转 mSm = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mSensor = mSm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSm.registerListener(mOrientationSensorListener, mSensor, SensorManager.SENSOR_DELAY_UI); public class OrientationSensorListener implements SensorEventListener { private static final int _DATA_X = 0; private static final int _DATA_Y = 1; private static final int _DATA_Z = 2; public static final int ORIENTATION_UNKNOWN = -1; private boolean sensor_flag = true; public static final String TAG = "xujun"; int mLastAngle=-1; AngleChangleListener mAngleChangleListener; public OrientationSensorListener(AngleChangleListener angleChangleListener){ mAngleChangleListener=angleChangleListener; } @Override public void onAccuracyChanged(Sensor arg0, int arg1) { // TODO Auto-generated method stub } @Override public void onSensorChanged(SensorEvent event) { float[] values = event.values; int orientation = ORIENTATION_UNKNOWN; float X = -values[_DATA_X]; float Y = -values[_DATA_Y]; float Z = -values[_DATA_Z]; /** * 这一段据说是 android源码里面拿出来的计算 屏幕旋转的 不懂 先留着 万一以后懂了呢 */ float magnitude = X * X + Y * Y; // Don't trust the angle if the magnitude is small compared to the y value if (magnitude * 4 >= Z * Z) { //屏幕旋转时 float OneEightyOverPi = 57.29577957855f; float angle = (float) Math.atan2(-Y, X) * OneEightyOverPi; orientation = 90 - (int) Math.round(angle); // normalize to 0 - 359 range while (orientation >= 360) { orientation -= 360; } while (orientation < 0) { orientation += 360; } } if (orientation > 225 && orientation < 315) { //横屏 sensor_flag = false; } else if ((orientation > 315 && orientation < 360) || (orientation > 0 && orientation < 45)) { //竖屏 sensor_flag = true; } // Log.i(TAG, "onSensorChanged: orientation=" + orientation+" mLastAngle="+mLastAngle); if(mLastAngle!=orientation && mAngleChangleListener!=null){ mAngleChangleListener.onChange(orientation); mLastAngle=orientation; } } }

设备旋转时保存Activity的交互状态

大家先看一下Activity的生命周期,我们知道如果我们不配置Activity的方向或者Activity的 android:configchang 属性的时候,每次旋转屏幕,Activity都会重新被创建出来。那我们要如何保存我们当前的状态呢。

其实我们可以考虑在 onPause() 或者在 onStop() 里面保存我们相应的数据,再在onCreate() 方法里面判断 savedInstanceState 是否有缓存我们的数据即可。 至于选择在onPause() 还是 onStop() 保存数据,得看具体的需求分析。 onPause() 在界面失去焦点的时候会回调, onStop() 方法在界面完全不可见的时候会回调。

private static final String KEY_INDEX = "index"; private int mCurrentIndex = 0; @Override protected void onCreate(Bundle savedInstanceState) { if (savedInstanceState != null) { mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0); } } @Override protected void onPause(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt(KEY_INDEX, mCurrentIndex); }

Demo 下载地址:ScreenDemo_jb51.rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-09-04 19:33:23

android中Activity横竖屏切换的那些事的相关文章

Android Activity 横竖屏切换的生命周期_Android

前言 在开发中常要处理横竖屏切换,怎么处理先看生命周期 申明 Activity 横竖屏切换时需要回调两个函数 ,所以在此将这个两个函数暂时看成是Activity 横竖屏切换的生命周期的一部分,这两个函数如下 onSaveInstanceState(Bundle outState) :Activity 即将销毁时保存数据 onRestoreInstanceState(Bundle savedInstanceState) : Activity 重建或者恢复时候取出数据 横竖屏切换生命周期 1.启动程

Android编程实现横竖屏切换时不销毁当前activity和锁定屏幕的方法_Android

本文实例讲述了Android编程实现横竖屏切换时不销毁当前activity和锁定屏幕的方法.分享给大家供大家参考,具体如下: 首先在Mainifest.xml的Activity元素中加入android:configChanges="orientation|keyboardHidden"属性 <activityandroid:name=".FileBrowser"android:label="@string/app_name"android:

Android布局之横竖屏切换

在默认情况下当屏幕从竖评变到横屏时会触发 onConfigurationChanged 事 件 在默认情况下会重新加载画面并显示和横屏一样的画面,这样会有2个问题, * 布局问题,在竖屏 显示的布局 到横屏中由于宽和高发生了变化所有多少 都会影响到布局(除非你定制2套画面在然后加个判断在横屏时怎么显示,在竖 屏时怎么显示),当然最简单的办法就是在 项目的AndroidManifest.xml中找到 你所指定的activity 中加上 o 只竖屏显示的话(android:screenOrienta

android:configChanges 屏幕横竖屏切换

出处:http://blog.csdn.net/djy1992/article/details/9378195 --->  android:screenOrientation="portrait" 当在AndroidManifest.xml文件中定义了android:screenOrientation="portrait",就表示当我们切换横竖屏的时候,屏幕的内容始终以竖屏显示,而不会根据屏幕的方向来显示内容 AndroidManifest.xml文件   &

解决Android手机屏幕横竖屏切换

Android中当屏幕横竖屏切换时,Activity的生命周期是重新加载(说明当前的Activity给销毁了,但又重新执行加载), 怎么使屏幕横竖屏切换时,当前的Activity不销毁呢? 1. 在AndroidManifest.xml中为Activity设置configChanges属性, application android:icon="@drawable/icon" android:label="@string/app_name"> <activ

Android中Activity之间的切换动画例子

Activity进行切换的时候可以加入一些炫酷的动画, 实现代码如下: MainActivity: package com.example.administrator.swichlayoutdemo; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListe

android实现在横竖屏切换时页面信息不被重置的示例分享_Android

当屏幕转动切换的时候 Android 机制是:销毁当前屏幕的 Activity ,然后重新开启一个新的适应屏幕改变的 Activity .那么,我们该如何在屏幕切换的时候页面信息不被重置呢? 解决实现:1.在 AnroidMainifest.xml 的 activity 元素中加入: 复制代码 代码如下: android:configChanges="orientation|keyboardHidden" 或 复制代码 代码如下: android:configChanges="

关于Android横竖屏切换及Activity重启周期的总结

禁止Android横竖屏和解决切换屏幕时重启Activity的方法 1.在AndroidManifest.xml的Activity配置中加入 android:screenOrientation="landscape"属性(landscape是横向,portrait是纵向).如: <activity android:name=".ContactsManagerActivity" android:label="@string/app_name"

android开发-Android 里把Activity伪装成Dialog后此Activity不能横竖屏切换?

问题描述 Android 里把Activity伪装成Dialog后此Activity不能横竖屏切换? Android 里把Activity伪装成Dialog后此Activity就不能横竖屏切换了?也不能回调onConfigurationChanged. 还有什么办法能使伪装的dialog 监听到手机横竖屏的变化么 解决方案 就用Activity,不可以吗~实现什么效果~ 解决方案二: 就用Activity,不可以吗~实现什么效果~ 解决方案三: 伪装成....还是Acticvitiy. 解决方案