需要了解橫豎屏切換關鍵知識
1.在Android設備的橫豎屏幕,每一次切換橫豎屏其實是在重新創建Activity,Activity會重新走一遍生命周期.從onCreate 到 onDestroy
2.在Activity類里的變量也會重新創建,這點需要注意!
判斷屏幕方向,方式一
判斷屏幕是否豎屏
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){ L.e("觸發豎屏"); } }
判斷屏幕是否橫屏
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){ L.e("觸發橫屏"); } }
判斷屏幕是否是未知方向
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_UNDEFINED){ L.e("未定義方向"); } }
判斷屏幕方向,方式二
這個方式其實是監聽activity的配置變化時的回調
在activity里重寫onConfigurationChanged方法
@Override public void onConfigurationChanged(Configuration newConfig) { L.e("newConfig.orientation="+newConfig.orientation); if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ L.e("觸發豎屏"); } if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){ L.e("觸發橫屏"); } super.onConfigurationChanged(newConfig); }
注意!,這個方法沒想象這么簡單.這個方法回調的條件: 這個方法要求,切換橫豎屏不在重新創建activity,就是activity不會再次onCreate,才會回調這個方法.所以正常情況下,你無法在橫豎屏后觸發這個回調.
為了觸發這個回調,我們需要在AndroidManifest.xml給目標Activity添加屬性 android:configChanges="orientation|screenSize":
<activity android:name=".test.TestActivity" android:configChanges="orientation|screenSize"/>
configChanges這個屬性控制着,我們activity在某些情況下是不需要重新創建activity的,這里的不重新創建意味着activity的生命周期將保持不變,不會重新走任何一個生命周期包括onResume.
這里設置方向orientation和尺寸screenSize,就會讓方向與尺寸改變時不會重新創建activity.當然還有以下幾種情況:
- “mcc“ 移動國家號碼,由三位數字組成,每個國家都有自己獨立的MCC,可以識別手機用戶所屬國家。
- “mnc“ 移動網號,在一個國家或者地區中,用於區分手機用戶的服務商。
- “locale“ 所在地區發生變化。
- “touchscreen“ 觸摸屏已經改變。(這不應該常發生。)
- “keyboard“ 鍵盤模式發生變化,例如:用戶接入外部鍵盤輸入。
- “keyboardHidden“ 用戶打開手機硬件鍵盤
- “navigation“ 導航型發生了變化。(這不應該常發生。)
- “orientation“ 設備旋轉,橫向顯示和豎向顯示模式切換。
- “fontScale“ 全局字體大小縮放發生改變
判斷屏幕方向,方式三
這個方法其實是最強的,因為它是監聽了方向傳感器的值.所以它能監聽獲取任意方向.
我們只要new一個OrientationEventListener,開啟就行了.注意它不是接口類,是一個抽象類.
private OrientationEventListener mOrientationEventListener; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); mOrientationEventListener = new OrientationEventListener(this) { @Override public void onOrientationChanged(int orientation) { L.e("onOrientationChanged: " + orientation); if (orientation > 350 || orientation < 20) { //0度 90 正豎屏 } else if (orientation > 70 && orientation < 110) { //90度 右橫屏 } else if (orientation > 160 && orientation < 200) { //180度 倒豎屏 } else if (orientation > 250 && orientation < 290) { //270度 左橫屏 } } }; if (mOrientationEventListener.canDetectOrientation()) { Log.v(TAG, "可以檢測方向"); mOrientationEventListener.enable();//開啟 } else { Log.v(TAG, "無法檢測方向"); mOrientationEventListener.disable(); } } @Override protected void onDestroy() { super.onDestroy(); mOrientationEventListener.disable();//注銷 }
最后注意,在退出時需要注銷關閉監聽.
另外還有一個更合適在方向監聽上使用的,配置參數 SensorManager.SENSOR_DELAY_NORMAL:
mOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) { // @Override public void onOrientationChanged(int orientation) { L.e("onOrientationChanged: " + orientation); } };
SensorManager.SENSOR_DELAY_NORMAL 的意思是,讓傳感器延遲,更適合在方向的監聽使用.所以如果你只需要方向上面的監聽推薦添加這個參數創建OrientationEventListener.
這樣設置延遲的好處是排除一些中間的波動值,返回的值會更加穩定,這樣你可以在判斷方向時,不會出現在邊界值上反反復復切來切去的問題.
設置當前屏幕方向
在AndroidManifest.xml的Activity里設置Activity
android:screenOrientation="portrait"
在activity里寫以下任意一個屬性
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//設置屏幕為橫屏, 設置后會鎖定方向 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//設置屏幕為豎屏, 設置后會鎖定方向 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);//方向未定義, 設置后放棄鎖定方向
注意,這里的鎖定方向意思是指,用戶將無法自己改變這個activity的方向. 包括自動切換屏幕的方向傳感器.
- SCREEN_ORIENTATION_UNSPECIFIED 方向未指定
- SCREEN_ORIENTATION_LANDSCAPE 方向橫屏
- SCREEN_ORIENTATION_PORTRAIT 方向豎屏
- SCREEN_ORIENTATION_USER 方向用戶
- SCREEN_ORIENTATION_BEHIND 方向背后
- SCREEN_ORIENTATION_SENSOR 方向傳感器
- SCREEN_ORIENTATION_NOSENSOR 方向沒有傳感器
- SCREEN_ORIENTATION_SENSOR_LANDSCAPE 傳感器橫向
- SCREEN_ORIENTATION_SENSOR_PORTRAIT 傳感器豎向
- SCREEN_ORIENTATION_REVERSE_LANDSCAPE 反轉橫向
- SCREEN_ORIENTATION_REVERSE_PORTRAIT 反轉豎向
- SCREEN_ORIENTATION_FULL_SENSOR 全傳感器
- SCREEN_ORIENTATION_USER_LANDSCAPE 用戶橫向
- SCREEN_ORIENTATION_USER_PORTRAIT 用戶豎向
- SCREEN_ORIENTATION_FULL_USER 方向用戶
- SCREEN_ORIENTATION_LOCKED 方向鎖定
end