一、橫豎屏切換設置:
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)
二、橫豎屏切換更改布局
如果要讓軟件在橫豎屏之間切換,由於橫豎屏的高寬會發生轉換,有可能會要求不同的布局。可以通過以下兩種方法來切換布局:
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"); // 豎屏
}
三、通過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"可以實現轉屏
判斷activity 是橫屏還是豎屏
方法 1: //根據設備配置信息
Configuration cf= this.getResources().getConfiguration(); //獲取設置的配置信息
int ori = cf.orientation ; //獲取屏幕方向
if(ori == cf.ORIENTATION_LANDSCAPE){
//橫屏
}else if(ori == cf.ORIENTATION_PORTRAIT){
//豎屏
}
方法2: 通過設備分辨率還判斷
DisplayMetrics dm = new DisplayMetrics();
mLauncher.getWindowManager().getDefaultDisplay().getMetrics(dm);
mWidth = dm.widthPixels;
mHeight = dm.heightPixels;
if (mHeight > mWidth){//layout port
// 豎屏 .......
}else{//layout land
// 橫屏 .......
}
設置程序 橫屏還是豎屏 有兩種方法 1:通過配置實習 2: 代碼實現
方法2://重寫activity onResume方法
@Override protected void onResume() {
/** * 設置為橫屏 */
if(getRequestedOrientation()!=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE :橫
//SCREEN_ORIENTATION_PORTRAIT:豎
}
super.onResume();
}
方法2: 配置androidManifest.xml實現
在activity 中加入 android:screenOrientation="landscape" 信息即可 該屬性有兩個值 portrait//豎 landscape//橫
<activity android:name="MainActivity" android:label="@string/app_name" android:screenOrientation="landscape">
</activity>
搞定 快去試試 吧 不過細心的朋友 會發現 咦 當我屏幕的方向 發生變化的時候為啥 activity 的onCreate 怎么會重新加載呢
原因是: 由於屏幕的旋轉會造出 當然的activity 元素關閉 從而造出activity重新加載 ,顯然這有時候並不是我們要的效果 , 那我們 在看看 如果解決這個問題吧
我們在androidManifest.xml 文件中 activity 節點加入紅色的 屬性
<activity android:name="MainActivity" android:label="@string/app_name" android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden">
</activity>
1、不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次
2、設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次
3、設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執行onConfigurationChanged方法
同時在Activity的Java文件中重載onConfigurationChanged(Configuration newConfig)這個方法,這樣就不會在布局切換或窗口切換時重載等方法。代碼如下:
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
//land
}
else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
//port
}
}
//------------------------------------------------------
android:screenOrientation=["unspecified" | "user" | "behind" |screenOrientation 用來指定Activity的在設備上顯示的方向,每個值代表如下含義:
"landscape" | "portrait" |
"sensor" | "nonsensor"]
"unspecified " |
默認值 由系統來判斷顯示方向.判定的策略是和設備相關的,所以不同的設備會有不同的顯示方向. |
"landscape " |
橫屏顯示(寬比高要長) |
"portrait " |
豎屏顯示(高比寬要長) |
"user " |
用戶當前首選的方向 |
"behind " |
和該Activity下面的那個Activity的方向一致(在Activity堆棧中的) |
"sensor " |
有物理的感應器來決定。如果用戶旋轉設備這屏幕會橫豎屏切換。 |
"nosensor " |
忽略物理感應器,這樣就不會隨着用戶旋轉設備而更改了 ( "unspecified "設置除外 )。 |