最近開發Android Camera相關的程序,被屏幕旋轉搞得頭大,一方面得考慮屏幕旋轉後布局的變化,另一方面得搞清楚屏幕的旋轉方向、角度與Camera的Preview角度的關系。本來通過重載Activity的onConfigurationChanged方法,可以檢測到屏幕旋轉,但發現有一個問題,它只能檢測水平方向與垂直方向的切換,無法檢測180度的跳轉(例如:水平方向突然轉180度到水平方向),所以最後不得不換成OrientationEventListener方法來解決問題。在這裡分享下經驗,並就此順便總結下Android開發中屏幕旋轉的處理吧。
1. 不做任何處理的情況下
如果沒有針對性地做任何處理的話,默認情況下,當用戶手機的重力感應器打開後,旋轉屏幕方向,會導致app的當前activity發生onDestroy-> onCreate,會重新構造當前activity和界面布局,很多橫屏/豎屏的布局如果沒有很好的設計的話,轉換為豎屏/橫屏後,會顯示地很難看。
如果想很好地支持屏幕旋轉,則建議在res中建立layout-land和layout-port兩個文件夾,把橫屏和豎屏的布局文件放入對應的layout文件夾中。
2. 如何設置固定的屏幕方向
在AndroidManifest.xml對應的 activity 屬性中,添加:
android:screenOrientation="landscape" //橫屏
android:screenOrientation="portrait" //豎屏
那麼,默認的情況下,應用啟動後,會固定為指定的屏幕方向,即使屏幕旋轉,Activity也不會出現銷毀或者轉向等任何反應。
3. 強制開啟屏幕旋轉效果
如果用戶的手機沒有開啟重力感應器或者在AndroidManifest.xml中設置了android:screenOrientation,默認情況下,該Activity不會響應屏幕旋轉事件。如果在這種情況下,依然希望Activity能響應屏幕旋轉,則添加如下代碼:
// activity的 onCreate 函數中
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
4. 屏幕旋轉時,不希望activity被銷毀
如果希望捕獲屏幕旋轉事件,並且不希望activity 被銷毀,方法如下:
(1)在AndroidManifest.xml對應的activity屬性中,添加:
android:configChanges="orientation|screenSize"
(2)在對應的activity中,重載函數onConfigurationChanged
@Override
public voidonConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
在該函數中可以通過兩種方法檢測當前的屏幕狀態:
第一種:
判斷newConfig是否等於Configuration.ORIENTATION_LANDSCAPE,Configuration.ORIENTATION_PORTRAIT
當然,這種方法只能判斷屏幕是否為橫屏,或者豎屏,不能獲取具體的旋轉角度。
第二種:
調用this.getWindowManager().getDefaultDisplay().getRotation();
該函數的返回值,有如下四種:
Surface.ROTATION_0,Surface.ROTATION_90,Surface.ROTATION_180,Surface.ROTATION_270
其中,Surface.ROTATION_0 表示的是手機豎屏方向向上,後面幾個以此為基准依次以順時針90度遞增。
(3) 這種方法的Bug
最近發現這種方法有一個Bug,它只能一次旋轉90度,如果你突然一下子旋轉180度,onConfigurationChanged函數不會被調用。