天天看點

我的Android進階之旅------>Android橫豎屏切換總結

在預設情況下當螢幕從豎評變到橫屏時會觸發 onConfigurationChanged 事件 在預設情況下會重新加載畫面并顯示和橫屏一樣的畫面,這樣會有2個問題,

  * 布局問題,在豎屏 顯示的布局 到橫屏中由于寬和高發生了變化所有多少都會影響到布局(除非你定制2套畫面在然後加個判斷在橫屏時怎麼顯示,在豎屏時怎麼顯示),當然最簡單的辦法就是在 項目的 AndroidManifest.xml中找到你所指定的activity 中加上

  o 隻豎屏顯示的話(android:screenOrientation="portrait")

  o 隻橫屏顯示的話(android:screenOrientation="landscape")

  * 畫面重新載入問題:在預設情況下橫豎 切換時會重新載入畫面,導緻一些不必要的資源浪費,更嚴重的是畫面上保持的資料(特别是遊戲方面)也都被重置了(當然你可以在重置前儲存這些資料到資料庫或者到文本檔案中),要怎麼避免在橫豎 切換時重新載入畫面,

  o 首先要在 AndroidManifest.xml中找到你所指定的activity 中加上android:configChanges="orientation|keyboardHidden"

  o 然後 在activity的邏輯進行中(代碼部分)去重載onConfigurationChanged事件,具體代碼參考一下:

  + @Override

  public void onConfigurationChanged(Configuration config) {

  super.onConfigurationChanged(config);

  }

在onConfigurationChanged中判斷要顯示的是橫屏還是豎屏然後在setcontentview

還有種方法

在res檔案夾下分别建立layout-port和layout-land,放豎屏和橫屏的布局檔案(同名的),會自動調用的。

以上就可以簡單的控制你的app畫面的顯示方式并且在顯示方式不變的情況下橫豎 屏切換時不會重新加載畫面,即優化的你的app同時使用者體驗也相應提高了。

摘一: 

在開發遊戲的時候,有些遊戲是隻能橫屏玩的,是以手機豎立放置的時候,要保持遊戲畫面依然橫屏。遊戲開發之初最好就确定是用橫屏還是豎屏,如果容忍轉屏的話,不僅需要作兩種界面布局,而且橫豎屏切換很可能會記憶體溢出,導緻程式崩潰。(文/jackliao) 

要做到這個要求其實很簡單,在AndroidManifest.xml裡面配置一下就可以了。加入這一行 

強制豎屏: 

我的Android進階之旅------>Android橫豎屏切換總結

android:screenOrientation="landscape"  

或者在代碼中: 

我的Android進階之旅------>Android橫豎屏切換總結

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);  

強制橫屏: 

我的Android進階之旅------>Android橫豎屏切換總結

android:screenOrientation="portrait"  

或者在代碼中: 

我的Android進階之旅------>Android橫豎屏切換總結

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);  

摘二: 

xml檔案中設定: 

  要實作這個目的,隻需要在AndroidManifest.xml裡聲明Activity的時候加上一個屬性:android:screenOrientation,屬性取值landscape為固定橫屏、portrait為固定縱螢幕。 

  代碼: 

  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE););//強制為橫屏 

  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//豎屏 

  ============延伸======== 

  螢幕會自動切換時,預設狀态的應用程式,會重新調用onCreate,相當于重新啟動了一次應用程式。同時,layout可能因為橫屏帶來不能合理适配的問題。為了解決旋屏和鍵盤切換引起的程式重新開機問題,還需要增加一個屬性:android:configChanges。這個屬性可以了解為一個監聽器,它将攔截旋屏和鍵盤切換事件,阻止程式重新開機而變為回調onConfigurationChanged方法。這裡常用的屬性取值為:keyboardHidden|orientation。 

摘三: 

Android 設定橫屏模式顯示,橫屏模式大部分情況能彌補豎屏的不足——字型小、鍵盤小、畫幅比例不合适,而且橫屏模式下能提供更華麗、更流暢的感官體驗,android 橫屏,android landscape mode

,android 強制橫屏,android 強制豎屏,android 橫屏布局,android 設定全屏模式,android 橫屏切換,android 設定橫屏。 

有些遊戲隻能橫屏,是以手機豎立放置的時候,要保持遊戲畫面依然橫屏,對于螢幕界面布局,在遊戲開發之初最好先确定是用橫屏還是豎屏,如果容忍轉屏的話,不僅需要作兩種界面布局,而且橫豎屏切換很可能會記憶體溢出,導緻程式崩潰。 

Android 設定橫屏布局 

1、AndroidManifest.xml 設定屬性: 

我的Android進階之旅------>Android橫豎屏切換總結

android:configChanges="orientation|keyboardHidden"  

代碼中設定: 

我的Android進階之旅------>Android橫豎屏切換總結

requestWindowFeature(Window.FEATURE_NO_TITLE);  

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);  

2、設定為全屏模式: 

我的Android進階之旅------>Android橫豎屏切換總結

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);  

3、強制為橫屏: 

我的Android進階之旅------>Android橫豎屏切換總結

4、強制為豎屏 

我的Android進階之旅------>Android橫豎屏切換總結

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);  

目錄:

引言

一、布局問題

二、重新載入問題

三、Q:橫豎屏生命周期的切換有可能是什麼樣的?

Activity在Configuration變化(比如裝置橫豎屏切換)時會重新開機Activity,即會執行onDestory()周期函數,然後onCreate(),重新建立Activity。這是因為這樣可以讓Activity動态适應Configuration,比如橫屏時使用橫屏的layout,drawable等resources,豎屏時使用豎屏的layout,drawable等resources。

(BTW,徹底禁止翻轉,可以設定android:screenOrientation的屬性為nosensor)

重新開機Activity可能導緻布局長寬不合适,也可能導緻大量資料的重新擷取,網絡連接配接的重建立立等問題,使用者體驗非常差。是以應該在Activity銷毀前儲存目前活動的狀态,在Activity再次Create的時候載入配置。

是以,Android橫豎屏切換要解決的問題就兩個:一、布局問題;二、重新載入問題。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.禁止切換橫屏或豎屏

可以在配置Activity的地方進行如下的配置

android:screenOrientation="portrait"

android:screenOrientation="landscape"

或者 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

這樣就可以保證是豎屏總是豎屏了,或者橫屏總是橫屏。

2.可以切換橫屏或豎屏

若要軟體在橫豎屏之間切換,由于橫豎屏的高寬會發生轉換,有可能會要求不同的布局。可以通過以下方法來切換布局:

1)layout-land和layout-port

在res目錄下建立layout-land(橫屏的layout)和layout-port(豎屏的layout)目錄,相應的layout檔案不變,比如main.xml。其他的不用管,模拟器會自動尋找。

2)onCreate()中判斷橫豎屏

通過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");

3)橫豎屏切換用onConfigurationChanged

這種方法缺點是動态适應差。比如橫豎屏切換時需要你自己寫代碼來使用不同的layout等resource,語言設定的動态改變等,不推薦.

首先要在配置Activity的時候進行如下的配置:

<activity android:name=".MyActivity"

android:configChanges="orientation|keyboardHidden"

android:label="@string/app_name">

另外需要重寫Activity的onConfigurationChanged方法。實作方式如下,不需要做太多的内容:

@Override

public void onConfigurationChanged(Configuration newConfig) {

super.onConfigurationChanged(newConfig);

// Checks the orientation of the screen

if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {

Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();

....

} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){

Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();

.....

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.不需要重新載入

在androidmanifest.xml中加入配置android:configChanges="orientation|keyboardHidden"

橫豎屏切換時調用onConfigurationChanged(Configuration newConfig)

注意:當橫屏變豎屏的時候,他會調用兩次onConfigurationChanged,而豎屏轉橫屏時他隻調用一次。

2.重新載入,儲存之前資料不變onSaveInstanceState()和onRestoreInstanceState()

Android橫豎屏切換時會觸發onSaveInstanceState,而還原時會産生onRestoreInstanceState。

注意  :

*我們不應該儲存那些依賴Activity的資料,比如Drawable,Adapter,View或者任何與Context相關聯的資料。因為上一個Activity已經沒有了,如果你還要保持這些資源的引用,可能導緻資源洩露。

3.重新載入,儲存之前資料不變onRetainNonConfigurationInstance()和getLastNonConfigurationInstance()

需要在重新載入過程中儲存之前的操作内容或資料,則需要儲存之前的資料。然後在activity的 onCreate()中取出來。當然,如此就不能設定android:configChanges()了,否則就不會調用onCreate()方法。那麼 資料可以儲存在哪呢?Android中四種存儲方法都可以。 

還可以用Android為我們提供了onRetainNonConfigurationInstance()方法來暫時儲存資料。

Instance本身。新建立的Activity可以繼承大量來至于Parent Activity State資訊。

onRetainNonConfigurationInstance這個方法最大的好處是:

* 當Activity曾經通過某個資源得到一些圖檔或者資訊,那麼當再次恢複後,無需重新通過原始資源位址擷取,可以快速的加載整個Activity狀态資訊。

* 當Activity包含有許多線程時,在變化後依然可以持有原有線程,無需通過重新建立程序恢複原有狀态。

* 當Activity包含某些Connection Instance時,同樣可以在整個變化過程中保持連接配接狀态。

注意:   

* 我們不應該儲存那些依賴Activity的資料,比如Drawable,Adapter,View或者任何與Context相關聯的資料。因為上一個Activity已經沒有了,如果你還要保持這些資源的引用,可能導緻資源洩露。   

* onRetainNonConfigurationInstance()在onSaveInstanceState()之後被調用。

* 調用順序同樣介于onStop() 和 onDestroy()之間。

使用方法如下:

public Object onRetainNonConfigurationInstance() {

final MyDataObject data = collectMyLoadedData();

return data;

在onCreate()中調用getLastNonConfigurationInstance(),擷取onRetainNonConfigurationInstance()儲存的資料。

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();

if (data == null) {

data = loadMyData();

...

Q:橫豎屏生命周期的切換有可能是什麼樣的?

如下:啟動一個Activity,

onCreate()

onStart()

onResume()

豎屏切換到橫屏:(調用一次生命周期)

onSaveInstanceState()

onPause()

onStop()

onDestroy()

onRestoreInstanceState()

橫屏切換到豎屏:(調用兩次生命周期)

b、設定Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時隻會執行一次。

c、設定Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,隻會執行onConfigurationChanged方法。

==================================================================================================

  作者:歐陽鵬  歡迎轉載,與人分享是進步的源泉!