【轉】Android橫豎屏切換問題 Android橫豎屏切換小結

Android橫豎屏切換總結(Android資料)

 

Android橫豎屏要解決的問題應該就兩個:html

一.佈局問題java

二.從新載入問題

android

1.佈局問題:若是不想讓軟件在橫豎屏之間切換,最簡單的辦法就是在項目的AndroidManifest.xml中找到你所指定的activity中加上android:screenOrientation屬性,他有如下幾個參數:面試

"unspecified":默認值 由系統來判斷顯示方向.斷定的策略是和設備相關的,因此不一樣的設備會有不一樣的顯示方向. 
"landscape":橫屏顯示(寬比高要長) 
"portrait":豎屏顯示(高比寬要長) 
"user":用戶當前首選的方向 
"behind":和該Activity下面的那個Activity的方向一致(在Activity堆棧中的) 
"sensor":有物理的感應器來決定。若是用戶旋轉設備這屏幕會橫豎屏切換。 
"nosensor":忽略物理感應器,這樣就不會隨着用戶旋轉設備而更改了("unspecified"設置除外)。
app

也能夠在Java代碼中經過setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)來設置。less

若是要讓軟件在橫豎屏之間切換,因爲橫豎屏的高寬會發生轉換,有可能會要求不一樣的佈局。能夠經過如下方法來切換佈局:異步

1)在res目錄下創建layout-land和layout-port目錄,相應的layout文件不變,好比main.xml。layout-land是橫屏的layout,layout-port是豎屏的layout,其餘的不用管,模擬器會自動尋找。ide

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 else if(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 else if(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橫屏豎屏切換的問題

1、禁止橫豎屏轉換

Android橫豎屏切換在手機開發中比較常見,不少軟件在開發過程當中爲了不橫豎屏切換時引起沒必要要的麻煩,一般禁止掉橫豎屏的切換,

經過在AndroidManifest.xml中設置activity中的android:screenOrientation屬性值來實現。

好比下列設置

android:screenOrientation="portrait"

則不管手機如何變更,擁有這個屬性的activity都將是豎屏顯示。

android:screenOrientation="landscape",爲橫屏顯示。

上述修改也能夠在Java代碼中經過相似以下代碼來設置

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)

另外,android中每次屏幕的切換動會重啓Activity,因此應該在Activity銷燬前保存當前活動的狀態,在Activity再次Create的時候載入配置,那樣,進行中的遊戲就不會自動重啓了!


2、橫豎屏切換

若是要讓軟件在橫豎屏之間切換,因爲橫豎屏的高寬會發生轉換,有可能會要求不一樣的佈局。能夠經過如下兩種方法來切換佈局:

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

 }

3、經過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和控件的尺寸位置信息,若是要處理尺寸和位置信息,必須經過消息異步或者延時調用。

4、完全禁止翻轉

固然若是要完全禁止翻轉,能夠設置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.}  

6、總結

總之,對於橫豎屏切換的問題,統計了下,你們的解決辦法是: 
①不理會。。
②只豎屏顯示(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);//控件
}
}

7、示例詳細步驟

//------ 第一步:得到許可 
須要在中添加相應許可

//------ 第二步:根據不一樣的目標,針對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;
}
}

8、備註:

一、不設置Activity的android:configChanges時,切屏會從新調用各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次
二、設置Activity的android:configChanges="orientation"時,切屏仍是會從新調用各個生命週期,切橫、豎屏時只會執行一次
三、設置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.全局字體大小縮放發生改變
 
 
一、不設置Activity的android:configChanges時,切屏會從新調用各個生命週期,切橫屏時會執行一次,切豎屏時會執行一次,網上有的說是,切豎屏會執行兩次,我在android2.3的模擬器和2.3手機上都試了,只有一次。可是在android2.2的模擬器上測試了,切豎屏的時候,會執行兩次聲明週期。
二、設置Activity的android:configChanges="orientation"時,切屏仍是會從新調用各個生命週期,切橫、豎屏時只會執行一次,並且,切豎屏的時候,最後還會調用onConfigurationChanged 。模擬器會按照以上說的執行,手機的話,不會執行聲明週期,只會執行 onConfigurationChanged
三、設置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 判斷橫屏仍是豎屏可使用兩種方式:

一、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();

二、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); // 背景自適應

 

 

 

 

1、禁止橫豎屏切換

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)

 

2、橫豎屏切換更改佈局

若是要讓軟件在橫豎屏之間切換,因爲橫豎屏的高寬會發生轉換,有可能會要求不一樣的佈局。能夠經過如下兩種方法來切換佈局:

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

}

 

3、經過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的生命週期。現
在給你們分析一下他切換時具體的生命週期是怎麼樣的:

一、新建一個Activity,並把各個生命週期打印出來

二、運行Activity,獲得以下信息

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

三、按crtl+f12切換成橫屏時

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

四、再按crtl+f12切換成豎屏時,發現打印了兩次相同的log

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

五、修改AndroidManifest.xml,把該Activity添加
android:configChanges="orientation",執行步驟3

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

六、再執行步驟4,發現不會再打印相同信息,但多打印了一行onConfigChanged

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

七、把步驟5的android:configChanges="orientation" 改爲
android:configChanges="orientation|keyboardHidden",執行步驟3,就只打印
onConfigChanged

onConfigurationChanged-->

八、執行步驟4

onConfigurationChanged-->
onConfigurationChanged-->

總結:

一、不設置Activity的android:configChanges時,切屏會從新調用各個生命週期,
切橫屏時會執行一次,切豎屏時會執行兩次

二、設置Activity的android:configChanges="orientation"時,切屏仍是會從新調
用各個生命週期,切橫、豎屏時只會執行一次

三、設置Activity的android:configChanges="orientation|keyboardHidden"時,
切屏不會從新調用各個生命週期,只會執行onConfigurationChanged方法

總結一下整個Activity的生命週期

補充一點,當前Activity產生事件彈出Toast和AlertDialog的時候Activity的生命
週期不會有改變

Activity運行時按下HOME鍵(跟被徹底覆蓋是同樣的):onSaveInstanceState -->
onPause --> onStop       onRestart -->onStart--->onResume

Activity未被徹底覆蓋只是失去焦點:onPause--->onResume

相關文章
相關標籤/搜索