Android横竖屏切换总结

Android横竖屏要解决的问题应该就两个:

一.布局问题

二.重新载入问题

1.布局问题:如果不想让软件在横竖屏之间切换,最简单的办法就是在项目的AndroidManifest.xml中找到你所指定的activity中加上android:screenOrientation属性,他有以下几个参数:

"unspecified":默认值 由系统来判断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的显示方向. 
"landscape":横屏显示(宽比高要长) 
"portrait":竖屏显示(高比宽要长) 
"user":用户当前首选的方向 
"behind":和该Activity下面的那个Activity的方向一致(在Activity堆栈中的) 
"sensor":有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换。 
"nosensor":忽略物理感应器,这样就不会随着用户旋转设备而更改了("unspecified"设置除外)。

也可以在Java代码中通过setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)来设置。

如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局。可以通过以下方法来切换布局:

1)在res目录下建立layout-land和layout-port目录,相应的layout文件不变,比如main.xml。layout-land是横屏的layout,layout-port是竖屏的layout,其他的不用管,模拟器会自动寻找。

2)通过 this.getResources().getConfiguration().orientation来判断当前是横屏还是竖屏然后来加载相应的 xml布局文件。因为当屏幕变为横屏的时候,系统会重新呼叫当前Activity的onCreate方法,你可以把以下方法放在你的onCreate中来检查当前的方向,然后可以让你的setContentView来载入不同的layout xml.
1 if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
2     Log.i("info","landscape");// 横屏
3 }
4 elseif(this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) {
5     Log.i("info","portrait");// 竖屏
6 }
在onConfigurationChanged()方法中也可以检测拥有硬键盘的键盘状态
1 //检测实体键盘的状态:推出或者合上   
2 if(newConfig.hardKeyboardHidden ==Configuration.HARDKEYBOARDHIDDEN_NO){
3    //实体键盘处于推出状态,在此处添加额外的处理代码
4 }
5 elseif(newConfig.hardKeyboardHidden ==Configuration.HARDKEYBOARDHIDDEN_YES){
6    //实体键盘处于合上状态,在此处添加额外的处理代码
7 }

2.重新载入问题。如果不需要从新载入,可以在AndroidManifest.xml中加入配置 android:configChanges="orientation|keyboardHidden",配置 android:configChanges的作用就是如文档所说的:Specify one or more configuration changesthat the activity will handle itself. If not specified, the activity will berestarted if any of these configuration changes happen in the system。这样在程序中Activity就不会重复的调用onCreate()甚至不会调用onPause、onResume.只会调用一个 onConfigurationChanged(Configuration newConfig)。如果需要重新载入,则不需要做任何修改。不过如果需要在重新载入过程中保存之前的操作内容或数据,则需要保存之前的数据。然后在 activity的onCreate()中取出来。当然,如此就不能设置android:configChanges()了,否则就不会调用 onCreate()方法。

如果要彻底禁止翻转,可以设置android:screenOrientation的属性为nosensor,如此就可以忽略重力感应带来的麻烦了。不过在模拟器上不管用,在真机上是正确的。android:screenOrientation="portrait"

则无论手机如何变动,拥有这个属性的activity都将是竖屏显示。

android:screenOrientation="landscape",为横屏显示。

这里提一个小知识,Android模拟器中,快捷键"Ctrl+F11/F12"可以实现转屏


Android横屏竖屏切换的问题

一、禁止横竖屏转换

Android横竖屏切换在手机开发中比较常见,很多软件在开发过程中为了避免横竖屏切换时引发不必要的麻烦,通常禁止掉横竖屏的切换,

通过在AndroidManifest.xml中设置activity中的android:screenOrientation属性值来实现。

比如下列设置

android:screenOrientation="portrait"

则无论手机如何变动,拥有这个属性的activity都将是竖屏显示。

android:screenOrientation="landscape",为横屏显示。

上述修改也可以在Java代码中通过类似如下代码来设置

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)

另外,android中每次屏幕的切换动会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置,那样,进行中的游戏就不会自动重启了!


二、横竖屏切换

如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局。可以通过以下两种方法来切换布局:

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"); // 横屏 

}  elseif(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT)

 {  

   Log.i("info", "portrait"); // 竖屏 

 }

三、通过onConfigurationChanged拦截横竖屏变换

按照二的操作,Activity每次横竖屏切换都会重新调用onPause->onStop-> onDestory->onCreate->onStart->onResume,为此涉及到内容和数据的保存和读取,否则转屏之前的内容就会消失了。很多时候这样的结果让程序繁琐,为此Android提供了在manifest中设置android:configChanges属性,从而让Activity不延续上述的重建流程。在Android工程的Mainfest.xml中配置Activity:android:configChanges="keyboardHidden|orientation",横竖屏切换之后就不会去执行OnCreat函数了,而是会去调用onConfigurationChanged()这样就能控制横竖屏的切换了。用户可以在Activity或View的onConfigurationChanged(ConfigurationnewConfig)函数中获取当前横竖屏参数。至于其调用顺序跟touch时间的传递顺序相似,不过他没有消费事件的概念,会顺次调用到每一个onConfigurationChanged函数。

需要重写Activity的onConfigurationChanged方法。实现方式如下,不需要做太多的内容:
@Override
      public voidonConfigurationChanged(Configuration newConfig) {
          super.onConfigurationChanged(newConfig);
          if(this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_LANDSCAPE) {
                // land donothing is ok
          } else if(this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) {
                // port donothing is ok
          }
      } 

需要注意的是,onConfigurationChanged函数中只能获得横竖屏切换后的参数,在该函数中获取不到新的Layout和控件的尺寸位置信息,如果要处理尺寸和位置信息,必须通过消息异步或者延时调用。

四、彻底禁止翻转

当然如果要彻底禁止翻转,可以设置android:screenOrientation的属性为nosensor,如此就可以忽略重力感应带来的麻烦了。不过在模拟器上不管用,在真机上是正确的。

这里提一个小知识,Android模拟器中,快捷键"Ctrl+F11/F12"可以实现转屏

五,自适应转换

如果想让它启动的时候是横屏的话就横屏表示,纵屏的话就纵屏表示,然后手机切换横竖屏就不能用了该怎么解决呢?

首先:在Mainfest.xml中追加

android:screenOrientation="sensor"android:configChanges="orientation|keyboardHidden"

这两个属性。

第二步:取得屏幕的长和宽,进行比较设置横竖屏的变量。

1. Display display = getWindowManager().getDefaultDisplay();  

2. int width = display.getWidth();  

3. int height = display.getHeight();  

4. if (width > height) {  

5.     orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;  //横屏

6. } else {  

7.     orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;  //竖屏

8. }  

第三步:在onConfigurationChanged()函数中追加this.setRequestedOrientation(orientation)就行了

1. public void onConfigurationChanged(Configuration newConfig) {  

2.     super.onConfigurationChanged(newConfig);  

3.     this.setRequestedOrientation(orientation);  

4. }  

但是这样的话你切到别的画面的时候再回到原画面,它就仍然是横的或者是纵的。怎么让它从别的屏幕回来后,又重新横竖屏布局呢?

只要在OnResume()中在设定下就行了。但是这个只支持横竖屏只有一个layout的。横竖屏分别对应layout的还不知道该怎么解决。

1. protected void onResume() {  

2.     orientation = ActivityInfo.SCREEN_ORIENTATION_USER;  

3.     this.setRequestedOrientation(orientation);  

4.     Display display = getWindowManager().getDefaultDisplay();  

5.     int width = display.getWidth();  

6.     int height = display.getHeight();  

7.     if (width > height) {  

8.         orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;  

9.     } else {  

10.        orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;  

11.    }  

12.    super.onResume();  

13.}  

六、总结

总之,对于横竖屏切换的问题,统计了下,大家的解决办法是:
①不理会。。
②只竖屏显示(android:screenOrientation="portrait")
 只横屏显示(android:screenOrientation="landscape")
③简单的防止重载:
 在 AndroidManifest.xml中加入:android:configChanges="orientation|keyboardHidden"
 在activity中重载onConfigurationChanged事件
 @Override
 publicvoid onConfigurationChanged(Configuration config) {
 super.onConfigurationChanged(config);
 }
④横竖屏分别布局
 横竖屏分别布局的方法是:
 在res下新建
 layout-land 横屏
 layout-port 竖屏
 然后把layout中的xml文件分别考到以上目录,修改布局就可以了代码中不做任何更改。
 在 AndroidManifest.xml文件中的主Activity中加入
 android:configChanges="orientation|keyboardHidden"
 然后在主Activity中的onConfigurationChanged加入
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);

if (config.orientation == Configuration.ORIENTATION_PORTRAIT){
setContentView(R.layout.main); //布局
tv = (TextView) findViewById(R.id.EditText01);//控件
}

if (config.orientation == Configuration.ORIENTATION_LANDSCAPE){
setContentView(R.layout.main); //布局
tv = (TextView) findViewById(R.id.EditText01);//控件
}
}

七、示例详细步骤

//------ 第一步:获得许可
需要在中添加相应许可

//------ 第二步:根据不同的目标,针对Activity进行设置

目标1屏蔽横竖屏的切换

步骤:为Activity设置一个默认的屏幕方向方法如下:
在AndroidManifest.xml中找到该Activity 添加代码:

android:name=".ActivityName"
android:screenOrientation="landscape"
>
设置Activity的默认方向为“横向”
此处的screenOrientation有如下选项:
==================================================================
= unspecified 默认值,由系统判断状态自动切换
= landscape 横屏
= portrait 竖屏
=user 用户当前设置的orientation值
= behind 下一个要显示的Activity的orientation值
= sensor 使用传感器 传感器的方向
= nosensor 不使用传感器 基本等同于unspecified
==================================================================
目标2:防止Activity的销毁

步骤:为Activity设置configChanges属性
在AndroidManifest.xml中找到该Activity 添加代码:

android:name=".ActivityName"
android:configChanges="orientation|keyboardHidden"
>
此处的configChanges有如下选项:
==================================================================
= orientation 屏幕在纵向和横向间旋转
= keyboardHidden 键盘显示或隐藏
= fontScale 用户变更了首选的字体大小
= locale 用户选择了不同的语言设定
= keyboard 键盘类型变更,例如手机从12键盘切换到全键盘
= touchscreen或navigation 键盘或导航方式变化,一般不会发生这样的事件
==================================================================
如果需要多个选项用"|"隔开
此处注意:如果是在实体机上测试横竖屏切换需要orientation选项
【重点】如果要使得程序可以在Android模拟器上测试需要写orientation|keyboardHidden
如果缺少了keyboardHidden选项不能防止Activity的销毁
并且在之后提到的onConfigurationChanged事件中只能捕获竖屏变横屏的事件 不能捕获横屏变竖屏

目标3:捕获横竖屏切换的事件
步骤:在Activity中(ActivityName.java)重写onConfigurationChanged事件
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
switch (newConfig.orientation)
{
//更改为LANDSCAPE
case (Configuration.ORIENTATION_LANDSCAPE):
//如果转换为横向屏时,有要做的事,请写在这里
break;
//更改为PORTRAIT
case (Configuration.ORIENTATION_PORTRAIT):
//如果转换为竖向屏时,有要做的事,请写在这里
break;
}
}

八、备注:

1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法


Android系统下横屏竖屏切换功能的实现

一:不同的layout
Android手机屏幕大小不一,有480x320, 640x360, 800x480.怎样才能让App自动适应不同的屏幕呢?
其实很简单,只需要在res目录下创建不同的layout文件夹,比如layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.Java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。
二:hdpi、mdpi、ldpi
在之前的版本中,只有一个drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三个,这三个主要是为了支持多分辨率。
drawable- hdpi、drawable- mdpi、drawable-ldpi的区别:
(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)
系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。
三:横屏竖屏
在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。以下步骤是网上流传的,不过我自己之前是通过图形化界面实现这个配置,算是殊途同归,有空我会把图片贴上来。
还要说明一点:每个activity都有这个属性screenOrientation,每个activity都需要设置,可以设置为竖屏(portrait),也可以设置为无重力感应(nosensor)。
要让程序界面保持一个方向,不随手机方向转动而变化的处理办法:

在AndroidManifest.xml里面配置一下就可以了。加入这一行
  • android:screenOrientation="landscape"
例如(landscape是横向,portrait是纵向):
Java代码:

  • <?xml version="1.0" encoding="utf-8"?>
  • <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ray.linkit"
  • android:versionCode="1"
    android:versionName="1.0">
  • <application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity
    android:name=".Main"
  • android:label="@string/app_name"
    android:screenOrientation="portrait">
  • <intent-filter>
    <action
    android:name="android.intent.action.MAIN" />
  • <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
  • </activity>
    <activity
    android:name=".GamePlay"
  • android:screenOrientation="portrait"></activity>
    <activity
    android:name=".OptionView"
  • android:screenOrientation="portrait"></activity>
    </application>
  • <uses-sdk android:minSdkVersion="3" />
  • </manifest>
另外, android中每次屏幕的切换动会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置,那样,进行中的游戏就不会自动重启了!
有的程序适合从竖屏切换到横屏,或者反过来,这个时候怎么办呢?可以在配置Activity的地方进行如下的配置android:screenOrientation="portrait"。这样就可以保证是竖屏总是竖屏了,或者landscape横向。
而有的程序是适合横竖屏切换的。如何处理呢?首先要在配置Activity的时候进行如下的配置:android:configChanges="keyboardHidden|orientation",另外需要重写Activity的onConfigurationChanged方法。实现方式如下,不需要做太多的内容:

  • @Override
  • public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
  • if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
    // land do nothing is ok
  • } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
    // port do nothing is ok
  • }
  • }


1.

总体来说有两种方案:

1.Android系统自动切换

  利用Android系统每次屏幕切换会重启Activity的特性,在OnCreat处自动加载不同显示状态下的layout。

  例:main.xml是竖屏状态下的layout,文件保存于res/layout文件夹中。为实现横屏切换,建立文件夹res/layout-land,在里面创建新的界面文件main.xml,与res/layout文件夹中文件同名。则当设备由竖屏切换到横屏,或者反之时,在onCreate()函数中直接执行setContentView(R.layout.main)即可自动加载不同的界面文件。

  另外,在res/layout-land中建立同名文件是用系统自动判断加载,也可以手动判断加载。如在res/layout文件夹中有竖屏界面main-P.xml及横屏界面main-L.xml,则可以在onCreate()函数中通过判断横竖屏状态以显式加载不同界面,代码:

int mCurrentOrientation =getResources().getConfiguration().orientation;

if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ){ 

  // If current screen isportrait

  setContentView(R.layout.main-P);

} else if ( mCurrentOrientation ==Configuration.ORIENTATION_LANDSCAPE ) {

  //If current screen islandscape

  setContentView(R.layout.main-L);

}

  由于android系统屏幕切换会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置。

2.利用Activity的onConfigurationChanged()方法手动切换

  为避免Android系统自动重启activity,需要在Androidmanifest.xml中相应Activity加上android:configChanges="keyboardHidden|orientation"属性,使相应的Activity不重启而是调用onConfigurationChanged(ConfigurationnewConfig)。

  例:res/layout下有竖屏界面main-P.xml及横屏界面main-L.xml。onCreate()时同理判断以显示不同的界面:

   @Override

   protectedvoid onCreate(Bundle icicle) {

 super.onCreate(icicle);

 int mCurrentOrientation =getResources().getConfiguration().orientation;

 if ( mCurrentOrientation ==Configuration.ORIENTATION_PORTRAIT ) { 

   // Ifcurrent screen is portrait

   setContentView(R.layout.main-P);

 } else if ( mCurrentOrientation ==Configuration.ORIENTATION_LANDSCAPE ) {

   //Ifcurrent screen is landscape

   setContentView(R.layout.main-L);

 }

 init();//初始化,赋值等操作

 findViews();//获得控件

 setListensers();//设置控件的各种监听方法

   }

  重载onConfigurationChanged():

   @Override

   publicvoid onConfigurationChanged (Configuration newConfig){

super.onConfigurationChanged(newConfig);


int mCurrentOrientation =getResources().getConfiguration().orientation;

if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ){ 

  // If current screen isportrait

  setContentView(R.layout.main-P);

  //注意,这里删除了init(),否则又初始化了,状态就丢失

  findViews();

  setListensers();

} else if ( mCurrentOrientation ==Configuration.ORIENTATION_LANDSCAPE ) {

  //If current screen islandscape

  setContentView(R.layout.main-L);

  //注意,这里删除了init(),否则又初始化了,状态就丢失

  findViews();

  setListensers();

}

   }

  以上代码中需要注意init()函数,若需要保存其它的状态,如Button及各种View的显示文字已经改变,在setListensers()务必进行恢复操作。

  同样,也可以使用res/layout/main.xml和res/layout-land/main.xml方式,则不需判断,直接使用setContentView(R.layout.main)即可。看代码:

   @Override

   protectedvoid onCreate(Bundle icicle) {

 super.onCreate(icicle);

 setContentView(R.layout.main);

 init();//初始化,赋值等操作

 findViews();//获得控件

 setListensers();//设置控件的各种监听方法

   }

  重载onConfigurationChanged():

   @Override

   publicvoid onConfigurationChanged (Configuration newConfig){

super.onConfigurationChanged(newConfig);


int mCurrentOrientation =getResources().getConfiguration().orientation;

if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ){ 

  // If current screen isportrait

  setContentView(R.layout.main);

  //注意,这里删除了init(),否则又初始化了,状态就丢失

  findViews();

  setListensers();

} else if ( mCurrentOrientation ==Configuration.ORIENTATION_LANDSCAPE ) {

  //If current screen islandscape

  setContentView(R.layout.main);

  //注意,这里删除了init(),否则又初始化了,状态就丢失

  findViews();

  setListensers();

}

   }

  其实在这种模式下,由于Android系统自动寻找不同界面文件,而Androidmanifest.xml中已定义了android:configChanges="keyboardHidden|orientation"只监听方向改变,因此onConfigurationChanged()方法还可以继续精简(除非在横竖屏下状态不同),直接设置界面、恢复状态即可:

   @Override

   publicvoid onConfigurationChanged (Configuration newConfig){

super.onConfigurationChanged(newConfig);


setContentView(R.layout.main);

//注意,这里删除了init(),否则又初始化了,状态就丢失

findViews();

setListensers();

   }

http://lishao378.blog.sohu.com/165342431.html

 

2.

横竖屏切换的响应

      如果没有设置强制横屏或者竖屏那么每次横竖屏切换的时候Activity都会被重新创建一次,这样就会存在一个问题横屏后会把图片拉伸可能在竖屏时感觉很协调的界面切换到横屏以后会被拉伸的很难看,比较好的解决办法是为横竖屏做两套图做两个布局文件,这样子程序中只需要监听屏幕切换的结果设置不同的布局 绘制不同的图片即可。




AndroidManifest.xml 中设置属性禁止重新创建Activity,并且添加屏幕切换监听。

  •           <activity android:name=".HandlerActivity"android:configChanges="orientation|keyboardHidden"/>


复制代码
设置后屏幕切换后就不会再次调用OnCreate()方法重新创建这个Activity,切换屏幕之前程序中的一些数据或者内容就不会因为重新创建Activity导致重置清空。每当切换横竖屏的时候系统会自己调用onConfigurationChanged()方法这样子就可以拿到当前屏幕的横竖屏状态,根据状态就可以做我们想做的事。

  • import android.app.Activity;
  • import android.content.res.Configuration;
  • import android.os.Bundle;
  • public class HandlerActivity extends Activity {
  •   @Override
  •   protected voidonCreate(Bundle savedInstanceState) {
  •       setContentView(R.layout.handler);
  •       super.onCreate(savedInstanceState);
  •   }
  •   @Override
  •   public voidonConfigurationChanged(Configuration newConfig) {
  •       int type =this.getResources().getConfiguration().orientation;
  •       if (type ==Configuration.ORIENTATION_LANDSCAPE) {
  •         //切换到了横屏
  •       } else if(type == Configuration.ORIENTATION_PORTRAIT) {
  •         //切换到了竖屏
  •       }
  •       super.onConfigurationChanged(newConfig);
  •   }
  • }

http://dev.10086.cn/cmdn/bbs/thread-61127-1-1.html

 3.一:不同的layout

Android手机屏幕大小不一,有480x320,640x360, 800x480.怎样才能让App自动适应不同的屏幕呢?
其实很简单,只需要在res目录下创建不同的layout文件夹,比如layout-640x360,layout-800x480,所有的layout文件在编译之后都会写入R.Java里,而系统会根据屏幕的大小自己选择合适的layout进行使用。
二:hdpi、mdpi、ldpi
在之前的版本中,只有一个drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三个,这三个主要是为了支持多分辨率。
drawable- hdpi、drawable- mdpi、drawable-ldpi的区别:
(1)drawable-hdpi里面存放高分辨率的图片,如WVGA (480x800),FWVGA (480x854)
(2)drawable-mdpi里面存放中等分辨率的图片,如HVGA (320x480)
(3)drawable-ldpi里面存放低分辨率的图片,如QVGA (240x320)
系统会根据机器的分辨率来分别到这几个文件夹里面去找对应的图片。
三:横屏竖屏
在开发程序时为了兼容不同平台不同屏幕,建议各自文件夹根据需求均存放不同版本图片。以下步骤是网上流传的,不过我自己之前是通过图形化界面实现这个配置,算是殊途同归,有空我会把图片贴上来。
还要说明一点:每个activity都有这个属性screenOrientation,每个activity都需要设置,可以设置为竖屏(portrait),也可以设置为无重力感应(nosensor)。
要让程序界面保持一个方向,不随手机方向转动而变化的处理办法:

在AndroidManifest.xml里面配置一下就可以了。加入这一行
  • android:screenOrientation="landscape"
例如(landscape是横向,portrait是纵向):
Java代码:

  • <?xml version="1.0"encoding="utf-8"?>
  • <manifestxmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ray.linkit"
  • android:versionCode="1"
    android:versionName="1.0">
  • <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
    <activity
    android:name=".Main"
  • android:label="@string/app_name"
    android:screenOrientation="portrait">
  • <intent-filter>
    <action
    android:name="android.intent.action.MAIN"/>
  • <categoryandroid:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
  • </activity>
    <activity
    android:name=".GamePlay"
  • android:screenOrientation="portrait"></activity>
    <activity
    android:name=".OptionView"
  • android:screenOrientation="portrait"></activity>
    </application>
  • <uses-sdkandroid:minSdkVersion="3" />
  • </manifest>
另外, android中每次屏幕的切换动会重启Activity,所以应该在Activity销毁前保存当前活动的状态,在Activity再次Create的时候载入配置,那样,进行中的游戏就不会自动重启了!
有的程序适合从竖屏切换到横屏,或者反过来,这个时候怎么办呢?可以在配置Activity的地方进行如下的配置android:screenOrientation="portrait"。这样就可以保证是竖屏总是竖屏了,或者landscape横向。
而有的程序是适合横竖屏切换的。如何处理呢?首先要在配置Activity的时候进行如下的配置:android:configChanges="keyboardHidden|orientation",另外需要重写Activity的onConfigurationChanged方法。实现方式如下,不需要做太多的内容:

  • @Override
  • public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
  • if (this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_LANDSCAPE) {
    // land do nothing is ok
  • } else if (this.getResources().getConfiguration().orientation== Configuration.ORIENTATION_PORTRAIT) {
    // port do nothing is ok
  • }
  • }

  • http://www.3gtarena.com/danapeixunjishu/androidpeixun/471.html

Android横竖屏切换相关总结

Android横竖屏要解决的问题应该就两个:一。布局问题;二。重新载入问题。

1.布局问题:如果不想让软件在横竖屏之间切换,最简单的办法就是在项目的 AndroidManifest.xml中找到你所指定的activity中加上android:screenOrientation属性,他有以下几个参数:

"unspecified"
默认值 由系统来判断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的显示方向.
"landscape"
横屏显示(宽比高要长)
"portrait"
竖屏显示(高比宽要长)
"user"
用户当前首选的方向
"behind"
和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)
"sensor"
有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换。
"nosensor"
忽略物理感应器,这样就不会随着用户旋转设备而更改了 ( "unspecified"设置除外 )。

也可以在Java代码中通过setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);来设置。

如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局。可以通过以下方法来切换布局:

1)在res目录下建立layout-land和layout-port目录,相应的layout文件不变,比如main.xml。layout-land是横屏的layout,layout-port是竖屏的layout,其他的不用管,模拟器会自动寻找。

2)通过this.getResources().getConfiguration().orientation来判断当前是横屏还是竖屏然后来加载相应的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");
}

2.重新载入问题。如果不需要从新载入,可以在androidmanifest.xml中加入配置 android:configChanges="orientation",配置android:configChanges的作用就是如文档所说的:Specify one or more configuration changes that the activity will handle itself. If not specified, the activity will be restarted if any of these configuration changes happen in the system。这样在程序中. Activity就不会重复的调用onCreate()甚至不会调用onPause.onResume.只会调用一个 onConfigurationChanged(Configuration newConfig)。

–*************其实在这里我遇到两个奇怪的问题,那就是

1.如果我在android:configChanges中只设置orientation,他依然会重新加载,只有设置了 orientation|keyboardHidden它才会只调用一个onConfigurationChanged(Configuration newConfig)

2.当横屏变竖屏的时候,他会调用两次onConfigurationChanged,而竖屏转横屏时他只调用一次onConfigurationChanged,真是太奇怪了。如果你知道,欢迎留言共同探讨*************–

如果需要重新载入,则不需要做任何修改。不过如果需要在重新载入过程中保存之前的操作内容或数据,则需要保存之前的数据。然后在activity的 onCreate()中取出来。当然,如此就不能设置android:configChanges()了,否则就不会调用onCreate()方法。那么数据可以保存在哪呢?Android中四种存储方法都可以,另外,还可以用Android为我们提供了 onRetainNonConfigurationInstance()方法来暂时保存数据。

下面为此举个例子:

保存临时图片:

1. @Override
2. public Object onRetainNonConfigurationInstance() {
3. final LoadedPhoto[] list = new LoadedPhoto[numberOfPhotos];
4.     keepPhotos(list);
5. return list;
6. }

之后便可以在activity的onCreate()函数中实现重新调用临时文件,在代码中需要判断系统是否需要重新加载临时文件。以下是放在OnCreate()函数中加载临时文件的代码:

1. private void loadPhotos() {
2. final Object data = getLastNonConfigurationInstance();
3. 
4. // The activity is starting for the first time, load the photos from Flickr
5. if (data == null) {
6.         mTask = new GetPhotoListTask().execute(mCurrentPage);
7.     } else {
8. // The activity was destroyed/created automatically, populate the grid
9. // of photos with the images loaded by the previous activity
10. final LoadedPhoto[] photos = (LoadedPhoto[]) data;
11. for (LoadedPhoto photo : photos) {
12.             addPhoto(photo);
13.         }
14.     }
15. }

对于大多数的情况并不需要做如上的操作,所以需要谨慎使用这个行文,毕竟最好的行为也并不适用于所有情况,如果应用的不好反而会给程序带来不必要的麻烦。

如果要彻底禁止翻转,可以设置android:screenOrientation的属性为nosensor,如此就可以忽略重力感应带来的麻烦了。不过不知道为什么,在模拟器上不管用,听别人说在真机上是正确的,我没有真机,等有了真机再试试看。


Android模拟器横屏切换方法

如果android模拟器已经启动后,可以使用快捷键F12或Ctrl+F11来切换。当然是用命令行仅仅启动模拟器可以使用参数emulator.exe -skinHVGA-L 来启动。

 
    需要注意的是,程序会重载onCreate,避免的方法可通过androidmanifest.xml文件中重新定义方向,以及根据Activity的重写onConfigurationChanged(Configuration newConfig)方法来控制。
 
Activity 的 ConfigChanges 属性
官方解释: 通过设置这个属性可以使Activity捕捉设备状态变化,以下是可以被识别的内容:
CONFIG_FONT_SCALE
CONFIG_MCC
CONFIG_MNC
CONFIG_LOCALE
CONFIG_TOUCHSCREEN
CONFIG_KEYBOARD
CONFIG_NAVIGATION
CONFIG_ORIENTATION
设置方法:将下列字段用“|”符号分隔开,例如:“locale|navigation|orientation”
Value
Description
“mcc“
The IMSI mobile country code (MCC) has changed — that is, a SIM hasbeen detected and updated the MCC.移动国家号码,由三位数字组成,每个国家都有自己独立的MCC,可以识别手机用户所属国家。
“mnc“
The IMSI mobile network code (MNC) has changed — that is, a SIM hasbeen detected and updated the MNC.移动网号,在一个国家或者地区中,用于区分手机用户的服务商。
“locale“
The locale has changed — for example, the user has selected a new language that text should be displayed in.用户所在地区发生变化。
“touchscreen“
The touchscreen has changed. (This should never normally happen.)
“keyboard“
The keyboard type has changed — for example, the user has plugged in an external keyboard.键盘模式发生变化,例如:用户接入外部键盘输入。
“keyboardHidden“
The keyboard accessibility has changed — for example, the user has slid the keyboard out to expose it.用户打开手机硬件键盘
“navigation“
The navigation type has changed. (This should never normally happen.)
“orientation“
The screen orientation has changed — that is, the user has rotated the device.设备旋转,横向显示和竖向显示模式切换。
“fontScale“
The font scaling factor has changed — that is, the user has selected a new global font size.全局字体大小缩放发生改变
 
 
1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行一次,网上有的说是,切竖屏会执行两次,我在android2.3的模拟器和2.3手机上都试了,只有一次。但是在android2.2的模拟器上测试了,切竖屏的时候,会执行两次声明周期。
2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次,而且,切竖屏的时候,最后还会调用onConfigurationChanged 。模拟器会按照以上说的执行,手机的话,不会执行声明周期,只会执行 onConfigurationChanged
3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

Android 禁止横屏竖屏切换模式解析,android 横屏布局,android 横屏切换,android 横屏事件,android 禁止横屏,对于可能需要禁止横屏和竖屏模式之间的切换,我们可以在Android 布局中加入相关语句,并间接锁定 activity 不让它重启。

对于可能需要禁止横屏和竖屏模式之间的切换,我们可以在 AndroidManifest.xml 里面加入这一行

以下为引用内容: 
android :screenOrientation="landscape " 

其中 landscape 是横向,portrait 是纵向,不过 android 中每次屏幕的切换动会重启 Activity ,所以应该在 Activity 销毁前保存当前活动的状态,在 Activity 再次 Create 的时候载入配置。在 activity 加下面的属性,将不会重启 activity :

以下为引用内容: 
android:configChanges="keyboardHidden|orientation".

而是去调用

以下为引用内容: 
onConfigurationChanged(Configuration newConfig). 

这样就可以在这个方法里调整显示方式。

Java 文件代码

以下为引用内容: 
@Override 
public void onConfigurationChanged(Configuration newConfig) { 
try { 
super.onConfigurationChanged(newConfig); 
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { 
// land 
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 
// port 
} 
} catch (Exception ex) { 
} 
}

http://www.desteps.com/application/mobile/0100216.html

Android 判断横屏还是竖屏,并且根据方向改变背景,android 横屏布局,android 判断横屏,android 判断横屏竖屏,android 切换背景,android 更换背景。

Android 判断横屏还是竖屏

android 判断横屏还是竖屏可以使用两种方式:

1、getSystemService

以下为引用内容: 
/* First, get the Display from the WindowManager */
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
/* Now we can retrieve all display-related infos */
int width = display.getWidth();
int height = display.getHeight();
int orientation = display.getOrientation();

2、getWindowManager

以下为引用内容: 
public int getScreenOrientation(){
Display getOrient = getWindowManager().getDefaultDisplay();
int orientation = getOrient.getOrientation();
// Sometimes you may get undefined orientation Value is 0
// simple logic solves the problem compare the screen
// X,Y Co-ordinates and determine the Orientation in such cases
if(orientation==Configuration.ORIENTATION_UNDEFINED){
Configuration config = getResources().getConfiguration();
orientation = config.orientation;
if(orientation==Configuration.ORIENTATION_UNDEFINED){
//if height and widht of screen are equal then
// it is square orientation
if(getOrient.getWidth()==getOrient.getHeight()){
orientation = Configuration.ORIENTATION_SQUARE;
}else{ //if widht is less than height than it is portrait
if(getOrient.getWidth() < getOrient.getHeight()){
orientation = Configuration.ORIENTATION_PORTRAIT;
}else{ // if it is not any of the above it will defineitly be landscape
orientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
}
}
return orientation; // return value 1 is portrait and 2 is Landscape Mode
}

android 判断横屏竖屏并切换背景

以下为引用内容: 
public static void AutoBackground(Activity activity,View view,int Background_v, int Background_h) { 
int orient=ScreenOrient(activity); 
if (orient == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {  
view.setBackgroundResource(Background_v); // 纵向
}else{
view.setBackgroundResource(Background_h); // 横向
} 
} 

其中 Background_v 是纵向时的背景图,Background_h 为横向时的背景图

然后在 activity 的 oncreate 方法中去调用

以下为引用内容: 
LinearLayout layout=(LinearLayout)findViewById(R.id.layout); 
androidUtil.AutoBackground(this, layout, R.drawable.bg_v, R.drawable.bg_h); // 背景自适应


 

一、禁止横竖屏切换

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"可以实现转屏

 

小结是对网上博文的简单修改

http://www.open-open.com/lib/view/open1328069449468.html


横竖屏切换时候Activity的生命周期--常考题目2012-10-18 14:57:42      我来说两句       作者:JoeBaby_ 收藏   我要投稿

 
横竖屏切换时候Activity的生命周期

        曾经遇到过一个面试题,让你写出横屏切换竖屏Activity的生命周期。现
在给大家分析一下他切换时具体的生命周期是怎么样的:

1、新建一个Activity,并把各个生命周期打印出来

2、运行Activity,得到如下信息

onCreate-->
onStart-->
onResume-->

3、按crtl+f12切换成横屏时

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

4、再按crtl+f12切换成竖屏时,发现打印了两次相同的log

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

5、修改AndroidManifest.xml,把该Activity添加
android:configChanges="orientation",执行步骤3

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->

6、再执行步骤4,发现不会再打印相同信息,但多打印了一行onConfigChanged

onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onConfigurationChanged-->

7、把步骤5的android:configChanges="orientation" 改成
android:configChanges="orientation|keyboardHidden",执行步骤3,就只打印
onConfigChanged

onConfigurationChanged-->

8、执行步骤4

onConfigurationChanged-->
onConfigurationChanged-->

总结:

1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,
切横屏时会执行一次,切竖屏时会执行两次

2、设置Activity的android:configChanges="orientation"时,切屏还是会重新调
用各个生命周期,切横、竖屏时只会执行一次

3、设置Activity的android:configChanges="orientation|keyboardHidden"时,
切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

总结一下整个Activity的生命周期

补充一点,当前Activity产生事件弹出Toast和AlertDialog的时候Activity的生命
周期不会有改变

Activity运行时按下HOME键(跟被完全覆盖是一样的):onSaveInstanceState -->
onPause --> onStop       onRestart -->onStart--->onResume

Activity未被完全覆盖只是失去焦点:onPause--->onResume

转载于:https://my.oschina.net/arthurdu/blog/177679

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值