Android 监听屏幕旋转事件(Activity 四 )

《》如果你所用的Android手机没有将屏幕方向锁定的话,那么所有的应用程序的界面都会有随着屏幕的方向的改变而发生改变,如果你的应用程序的界面没有针对屏幕的改变而在代码上做出一些适应的操作的话,那么手机就会以硬性的方式将应用程序界面强行适应屏幕的方向,但是这时就有可能使界面变得非常的丑;下面就介绍一些常用的有关屏幕方向改变的方法

1、强行设定应用程序的显示方向

也就说,我们可以指定应用程序不理睬屏幕的旋转,这是在Manifest.xml文件中配置Activity的时候指定的,

<activity>节点的android:screenOrientation属性可以完成该项任务,示例代码如下:

<activity android:name=".EX01"
    android:label="@string/app_name"
    android:screenOrientation="portrait"> 
    // 值为portrait时强制为竖屏, 值为landscape时强制为横屏
</activity>

当然我们也可以在onCreate方法中的靠前位置,使用java代码来设定

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATTION_LANDSCAPE); 
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATTION_PORTRAIT); 

 

2、强制开启屏幕旋转效果

如果用户的手机没有开启重力感应器或者在AndroidManifest.xml中设置了android:screenOrientation,默认情况下,该Activity不会响应屏幕旋转事件。如果在这种情况下,依然希望Activity能响应屏幕旋转,则添加如下代码:

// 在activity的 onCreate 函数中添加

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);

 

3、监听屏幕旋转

虽然上面的前言部分已经说明,屏幕旋转时会硬性的使应用程序适应屏幕方向,但是实际上不是这么简单,实际上当屏幕发生旋转(当手机的方向锁没有开启,并且没用强行设定屏幕显示方向),那么程序是上将会做以下几个步骤:

①调用当前的Activity的onSaveInstanceState(Bundle outState)去保存应用中的一些数据,你可以重写这个方法

然后调用onDestroy()销毁当前的Activity

③重新调用onCreate()或onRestoreInstanceState()方法去重新创建一个Activity(也就是说,程序会重新将onCreate中的代码在执行一遍)

-----好了,你想如果我们的onCreate方法中没有任何的处理的话,那么就会产生所谓的硬性的适应问题,但是我们可以在写onCreate的代码的时候,就分成两部分,也就是说:我们先创建两个布局文件,一个是在横屏的状态下使用的,一个是在竖屏状态下使用的,好了,之后写onCreate的代码的时候首先判断当前的屏幕的方向,如果是横屏的话,那么就使用横屏布局文件,如果是竖屏的话,就使用竖屏布局文件,那么这个问题就解决了

-----除此之外,还要说明的一点是onSaveInstanceState(Bundle outState)到底怎么用:当屏幕发生旋转的时候会调用这个方法,这里的参数Bundle,就是让我们来封装在屏幕  未旋转前时想要保存的数据的,之后调用onDestroy()销毁当前的Activity,最后重新调用onCreate(Bundle savedInstanceState),这时outState就会赋给savedInstanceState,这样的话,我们在onCreate中重新创建Activity的时候,可以用之前保存的数据来初始化重新创建的Activity,这很重要,因为一个应用程序在整个运行过程中,不论在横屏和竖屏,数据的变化都要有一致性,不能因为屏幕发生改变,就让用户从头开始重新操作一遍

-----实际上,我们如果是为了保存用户之前操作的数据的话,那么我们通常不用Bundle来封装,只要把那些和界面相关的数据的组件设为Activity的全局变量,就没有问题了,至于那些提交数据,直接提交数据库就Ok了,但是有上面的用法,不要忘了;

-----除此之外,由于屏幕旋转时,一定会触发onSaveInstanceState(Bundle outState)方法,那么我们完全可以将这个方法作为屏幕旋转的监听器

下面就举一个例子:

注意判断横屏和竖屏并不是简单的事,因为Android中规定,只有是完全竖和横才能够返回ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE、ActivityInfo.SCREEN_ORIENTATION_PORTRAIT 而这在实际中几乎无法存在这样的情况,所以我们特别写了一个判定屏幕方向的方法

 

activity_orientation1.xml文件 , 当竖屏时,加载这个布局


 

复制代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.penglee.screenorientation.OrientationActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="现在是竖屏" />

</RelativeLayout>
复制代码

 

 

 

activity_orientation2.xml文件 , 当横屏时,加载这个布局


 

复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="现在是横屏" />

</LinearLayout>
复制代码

 

OrientationActivity.java文件


 

复制代码
public class OrientationActivity extends Activity {
    
    final String LOG = "------ScreenOrientation------" ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //强行开启屏幕旋转效果
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
        if(savedInstanceState == null){
            setContentView(R.layout.activity_orientation1);
        }
        if(savedInstanceState != null){
            //横屏
            if( ScreenOrient(this)==ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE  )
                setContentView(R.layout.activity_orientation1);
            //竖屏
            if( ScreenOrient(this)==ActivityInfo.SCREEN_ORIENTATION_PORTRAIT  )
                setContentView(R.layout.activity_orientation2);    
            String temp = savedInstanceState.getString("data_key") ;
            Log.d(LOG , "重新创建了Activity,之前保存的内容是"+temp) ;
        }
    }
    
    //判定当前的屏幕是竖屏还是横屏
    public int ScreenOrient(Activity activity)
    {
        int orient = activity.getRequestedOrientation(); 
        if(orient != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE && orient != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            WindowManager windowManager = activity.getWindowManager();  
            Display display = windowManager.getDefaultDisplay();  
            int screenWidth  = display.getWidth();  
            int screenHeight = display.getHeight();  
            orient = screenWidth < screenHeight ?  ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        }
        return orient;
    }

    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        String tempData = "Something you want to save";
        outState.putString("data_key", tempData);
        Log.d(LOG, "onSaveInstanceState..");
    }
}
复制代码

 

好了大功告成!还有一些小的方法之后在说

敬请关注:http://group.cnblogs.com/27030/

 

posted @   RoperLee  阅读(10708)  评论(1编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示