Android橫屏豎屏切換的問題

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方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章