Ⅰ android屏幕配適、版本配適與多語言支持
目前主流的屏幕密度:240dpi (480 * 800px) , 320dpi (720*1280px) , 480dpi(1080*1920px)現在新出的手機幾乎全是全高清屏(1080*1920px)
Android圖片資源目錄
mdpi [1倍]160dpi
hdpi [1.5倍] 240dpi
xhdpi [2倍] 320dpi
xxhdpi [3倍] 480dpi
xxxhdpi [4倍] 640dpi
因此對其他圖片資源的建議是:
a.一般採用720 * 1280的屏幕尺寸設計,這樣切圖可以直接適配720 * 1280的機型。
b.720 * 1280下切的圖基本可以適配大部分機型。
d.適配480 * 800的機型,只需要把切圖 * 0.75。
e.適配1080 * 1920 的機型,只需要把切圖 * 1.50即可。
a.以720 * 1280作為設計標准,畫布大小定位720 * 1280 (以後1080*1920px做標准亦可,類推)
b.只使用偶數單位的尺寸
c.盡量只使用 24pt, 28pt , 32pt, 44pt大小的字體
d.設計完成之後,所有尺寸的px值除以2作為dp數據交給開發人員
e.三份切圖,分別是:xhdpi,hdpi,mdpi的資源,如果要切一份就使用xhdpi
柵格系統的最小單位是8dp,一切距離、尺寸都應該是8dp的整數倍,所有可操作元素最小點擊區域尺寸為48dp X 48dp。以下是一些常見的尺寸與距離:
有時候在自定義view,draw的時候單位往往是px,要做一個dpi的轉換,需要通過該類獲取屏幕的信息,如:屏幕密度,寬高等。
a.盡量使用線性布局(LinearLayout)和相對布局(RelateLayout),盡量不使用絕對布局(AbsoluteLayout)和幀布局(FrameLayout)。
b.盡量使用wrap_content、mach_parent讓view自適應或最大化,盡量不要寫寬高的值。
c.使用線下布局的百分比weight權重時,要把能伸縮方向的寬度寫成「0dp「,如果寫成wrap_coent會使布局效果不佳等問題。
d.盡量使用android的Shape自定義view背景,這樣會隨之自適應。
e.ImageView的ScaleType有幾種方式:matrix(默認)、center、centerCrop、centerInside、fitCenter、fitEnd、fitStart、fitXY;盡量使用fitCenter按比例擴大至view寬度,能取得較好適配和顯示效果。(更多請參考: Android中的ImageView配適 )
f.獲取屏幕解析度信息,進行動態適配。(參考第三大點)
a.把屏幕設置成單一的橫屏或豎屏:
b.根據橫豎屏載入不同布局(android: screenOrientation="sensor")
通過this.getResources().getConfiguration().orientation來判斷當前是橫屏還是豎屏,然後在onCreate方法中載入不同的布局
採用第二種方式要注意的有兩點
布局問題:
需要在res目錄先建立layout-land和layout-port目錄相應的xml文件名字相同,然後在兩個文件夾下創建相同名字的兩套xml,系統就會根據不同的屏幕來進行自動尋找。
切換時activity的生命周期:
activity生命周期在切換橫豎屏會有一些有趣的變化
a.不設置activity的android:configChanges時,切換橫屏,activity的生命周期會重新調用一次,但是切換豎屏時,生命周期會重新調用兩次。
b.當設置activity的android:configChanges=「orientation」時,切換橫豎屏都會重新調用各生命周期一次。
c.當設置activity的android:configChanges=「orientation|keyboardHidden」(大於api13時,需要設為「orientation|screenSize」)時,切換橫豎屏不會重新調用各生命周期,只會調用onConfigurationChanged方法。
一般設為b或者c
平板應用的特性:
對於大屏幕的平板8英寸以上(參考ipad mini,現在很多高端手機都是5-6英寸了,8英寸以上視為平板吧),基與平板應用的特性,平板應用開發一般採取如下兩種策略
1)兼容模式
採用單activity(或者盡量少activity)+多fragment的結構開發應用,在layout資源文件中創建三套布局:手機布局、平板橫屏布局、平板豎屏布局。
優點:
只需要維護一個app
缺點:
設計及實現的難度變大,更復雜,有時候需要採取折衷方案
手機apk上由於含有平板的大解析度圖片資源(設計上可以減少內置資源)
2)開發另一套只適配平板的app
優點:
與手機app分離獨立。不會因為要兼容而採用一些折衷方案,影響其性能、內存
設計和實現更加自由
缺點:
需要維護兩套app
目前谷歌推薦第一種方案,但是國內很多應用是採取第二種方案。
可以通過判斷sdk的版本(Build.VERSION.SDK_INT),來為能夠使用的版本進行個性化設置
例如:沉浸式狀態欄配適
在Android系統4.4以前,狀態欄的背景色和字體顏色都是不能改變的。但是4.4以後Google增加了改變狀態欄背景透明的方法。可以通過判斷sdk的版本,來為能夠使用的版本進行個性化設置:
沉浸式狀態欄是Android在5.0中引入的,在5.0之前是沒有的,並且在Android6.0中沉浸式狀態欄的使用方法和5.0不一樣,因此需要做到版本兼容,針對於不同的Android進行適配,同樣也是通過判斷Build.VERSION.SDK_INT來區分版本,進行個性化配適
沉浸式狀態欄的實現方式有好幾種,更多請參考 沉浸式狀態欄的實現
原則:內置圖片資源不應該出現文字(如果出現文字需要具備)、所有的文字需要放在res資源目錄特定語言目錄下。
Ⅱ Android之Activity全面解析,有些知識點容易忘記
Activity作為安卓四大組件之一,是最重要也是用得最多的組件,涉及的知識點非常多,有些知識點平時開發很少用到,但在某些場景下需要特別注意,本文詳細整理了Activity涉及的知識點,供開發參考。
針對Activity可以提出很多問題,如:
Activity 的生命周期?
Activity 之間的通信方式?
Activity 各種情況下的生命周期?
橫豎屏切換時 Activity 的生命周期?
前台切換到後台,然後再回到前台時 Activity 的生命周期?
彈出 Dialog 的時候按 Home 鍵時 Activity 的生命周期?
兩個Activity之間跳轉時的生命周期?
下拉狀態欄時 Activity 的生命周期?
Activity 與 Fragment 之間生命周期比較?
Activity 的四種 LaunchMode(啟動模式)的區別?
Activity 狀態保存與恢復?
Activity的轉場動畫有哪些實現方式?
Activity的生命周期中怎麼獲取控制項寬高?
onNewIntent的執行時機?
如何連續退出多個Activity?
如何把Acitivty設置成Dialog樣式 ,android:theme="@android:style/Theme.Dialog"
關於橫豎屏切換的生命周期,對應不同的手機,由於廠商定製的原因,會有不同的效果,如設置了configChanges="orientation」在有些手機會執行各個生命周期,但有些手機卻不會執行。
網上常見的結論如下:
但實際的測試如下:
可以看出,不同廠商的手機切屏生命周期會有差異。
從API 13以上,當設備在橫豎切屏時,「屏幕尺寸」也會發生變化,因此為了杜絕切屏導致頁面銷毀重建,需要加上screenSize,使用設置4,即 android:configChanges="orientation|keyboardHidden|screenSize" .
Activity的四種狀態如下:
在activity處於paused或者stoped狀態下,如果系統內存緊張,可能會被銷毀,當重回該activity時會重建,正常返回和被回收後返回的生命周期如下:
如果是回收後返回,onCreate的參數savedInstanceState不為空。
有哪些場景會觸發onNewIntent回調呢?跟啟動模式有關,首先該Activity實例已經存在,再次啟動才可能觸發。一種情況是啟動模式是singleTask或者singleInstance,無論該activity在棧中哪個位置,都會觸發onNewIntent回調,並且把上面其他acitivity移除,另一種情況是啟動模式是singleTop或者以FLAG_ACTIVITY_SINGLE_TOP啟動,並且該activity實例在棧頂,會觸發onNewIntent,如果不在棧頂是重新創建的,不會觸發。
在實際業務開發中,往往碰到需要連續退出多個activity實例,下面整理了幾種常見方法:
● 發送特定廣播
1、在需要處理連續退出的activity注冊該特定廣播;
2、發起退出的activity發送該特定廣播;
3、接收到該廣播的activity 調用finish結束頁面。
● 遞歸退出
1、用startActivityForResult啟動新的activity;
2、前一個頁面finish時,觸發onActvityResult回調,再根據requestCode和resultCode處理是否finish,達到遞歸退出的效果。
● FLAG_ACTIVITY_CLEAR_TOP
通過intent.setFlag(Intent.FLAG_ACTIVITY_CLEAR_TOP)啟動新activity,如果棧中已經有該實例,則會把該activity之上的所有activity關閉,達到singleTop啟動模式的效果。
● 自定義activity棧
1、自定義activity列表,新打開activity則加入棧中,關閉則移除棧;
2、需要退出多個activity時,則循環從棧中移除activity實例,並調用finish。
在討論Activity啟動模式經常提到任務棧,那到底什麼是任務棧?
任務是一個Activity的集合,它使用棧的方式來管理其中的Activity,這個棧又被稱為返回棧(back stack),棧中Activity的順序就是按照它們被打開的順序依次存放的。返回棧是一個典型的後進先出(last in, first out)的數據結構。下圖通過時間線的方式非常清晰地向我們展示了多個Activity在返回棧當中的狀態變化:
taskAffinity 任務相關性,可以用於指定一個Activity更加願意依附於哪一個任務,在默認情況下,同一個應用程序中的所有Activity都具有相同的affinity, 名字為應用的包名。當然了,我們可以為每個 Activity 都單獨指定 taskAffinity 屬性(不與包名相同)。taskAffinity 屬性主要和 singleTask 啟動模式和 allowTaskReparenting 屬性配對使用,在其他情況下沒有意義。
taskAffinity 有下面兩種應用場景:
分為顯示啟動和隱式啟動。
(1)顯示啟動
直接指定待調整的Activity類名。
(2)隱式啟動
Intent 能夠匹配目標組件的 IntentFilter 中所設置的過濾信息,如果不匹配將無法啟動目標 Activity。IntentFilter 的過濾信息有 action、category、data。
IntentFilter 需要注意的地方有以下:
● 一個 Activity 中可以有多個 intent-filter
● 一個 intent-filter 同時可以有多個 action、category、data
● 一個 Intent 只要能匹配任何一組 intent-filter 即可啟動對應 Activity
● 新建的 Activity 必須加上以下這句,代表能夠接收隱式調用
<category android:name="android.intent.category.DEFAULT" />
只要匹配一個action即可跳轉,注意的是action要區分大小寫。
規則:如果intent中有category,則所有的都能匹配到intent-filter中的category,intent中的category數量可用少於intent-filter中的。另外,單獨設置category是無法匹配activity的,因為category屬性是一個執行Action的附加信息。
intent不添加category會匹配默認的,即 「android:intent.category.DEFAULT」
如果上面例子,如果去掉intent.setAction("action_name"),則會拋出異常:
規則:類似action,但data有復雜的結構,只要匹配一個data並且與data中所有屬性都一致就能匹配到Activity,只要有1個屬性不匹配,都無法找到activity。
data的結構:
data 主要是由 URI 和 mimeType 組成的。
URI 可配置很多信息,的結構如下:
與url類似,例如:
mineType:指資源類型包括文本、圖片、音視頻等等,例如:text/plain、 image/jpeg、video/* 等
下面看下data匹配的例子:
只匹配scheme
只匹配scheme也是能匹配到activity的。
匹配scheme、host、port
將上面的data改為
匹配mineType
如果有mineType,則不能僅設置setData或setMineType了,因為setData會把mineType置為null,而setMineType會把data置為null,導致永遠無法匹配到activity,要使用setDataAndType。
使用scheme的默認值contentfile
注意該方法需要在startAtivity方法或者是finish方法調用之後立即執行,不能延遲,但可以在子線程執行。
而在windowAnimationStyle中存在四種動畫:
activityOpenEnterAnimation // 打開新的Activity並進入新的Activity展示的動畫
activityOpenExitAnimation // 打開新的Activity並銷毀之前的Activity展示的動畫
activityCloseEnterAnimation //關閉當前Activity進入上一個Activity展示的動畫
activityCloseExitAnimation // 關閉當前Activity時展示的動畫
overridePendingTransition的方式比較生硬,方法也比較老舊了,不適用於MD風格,google提供了新的轉場動畫ActivityOptions,並提供了兼容包ActivityOptionsCompat。
我們知道在onCreate和onResume裡面直接獲取到控制項寬高為0,那有什麼辦法獲取到控制項的實際寬高?只要有onWindowFocusChanged、view.post、ViewTreeObserver三種方式獲取。
當用戶點擊桌面圖標啟動APP時,背後的流程如下:
我們看到的手機桌面是Launch程序的界面,點擊應用圖標會觸發點擊事件,調用startActivity(intent),然後通過Binder IPC機制,與ActivityManagerService(AMS)通訊,AMS執行一系列操作,最終啟動目前應用,大概流程如下:
通過PackageManager的resolveIntent()收集跳轉intent對象的指向信息,然後通過grantUriPermissionLocked()方法來驗證用戶是否有足夠的許可權去調用該intent對象指向的Activity。如果有許可權,則在新的task中啟動目標activity,如果發現沒有進程,則先創建進程。
如果進程不存在,AMS會調用startProcessLocked創建新的進程,在該方法中,會通過socket的通訊方式通知zygote進程孵化新的進程並返回pid,在新的進程中會初始化ActivityThread,並依次調用Looper.prepareLoop()和Looper.loop()來開啟消息循環。
創建好進程後下一步要將Application和進程綁定起來,AMS會調用上一節創建的ActivityThread對象的bindAppliction方法完成綁定工作,該方法會發送一條BIND_APPLICATION的消息,最終會調用handleBindApplication方法處理消息,並調用makeApplication方法處理消息,載入APP的classes到內存中。
通過前面的步驟,系統已經擁有了該Application的進程,後續的啟動則是從已存在其他進程中啟動Acitivity,即調用realStartAcitvityLocked,該方法會調用Application的主線程對象ActivityThread的sheleLaunchActivity方法,在方法中會發送LAUNCH_ACTIVITY到消息隊列,最終通過handleLaunchActivity處理消息,完成Acitivty的啟動。
Activity
Activity 的 36 大難點,你會幾個?「建議收藏」
[譯]Android Application啟動流程分析
Ⅲ android 屏幕旋轉生命周期和setRequestedOrientation強制旋轉
屏幕會根據當前感測器進行自動旋轉,旋轉之後,activity屏幕的 生命周期不會發生變化 ,在activity中只會回調onConfigurationChanged方法
可見每次旋轉onDestory()方法都會被調用,如果要保存一些activity被銷毀前的數據的可以在onSaveInstanceState()方法中通過Bundle去保存
當我們調用了:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
或者
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
之後屏幕不會再自動旋轉回來的情況
關於這點:我在b站App端也發現相關問題,點進b站的播放視頻界面,我們手機開啟屏幕自動旋轉,當我們橫豎屏旋轉的時候是可以正常橫豎屏切換的,但是我們點擊視頻右下角的放大(就是橫屏)之後,自動旋轉就失效了,要豎屏的話需要再點擊一次
關於這個問題,就是我們說的setRequestedOrientation之後重力感測失效的問題,處理的方法也很簡單
在AndroidManifest.xml中設置了android:configChanges="orientation|keyboardHidden|screenSize的基礎上,在onConfigurationChanged中調用 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR) 方法,使其恢復重力感測即可
Ⅳ Android橫豎屏切換的生命周期以及配置
同個Activity而言,沒有切換之前的生命周期,如下:
旋轉屏幕之後,生殲老命周期會如下:
配置 1 適用我們普通應用,固定方向的開發,配置 2 適用於音氏緩升視頻開哪兄發,游戲開發。
Ⅳ 如何讓Android橫豎屏切換時不銷毀當前activity
manifest中為相應的Activity設置android:configChanges屬性即可
Andorid 3.2以前的SDK可以使用如下配置
android:configChanges="orientation|keyboardHidden"
而Adnroid 3.2以後的SDK必須添加一個screenSize屬性,具體如下
android:configChanges="keyboardHidden|orientation|screenSize"
或者
android:configChanges="orientation|screenSize"
對android:configChanges的總結
1、不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次(在三星4.0設備上切橫屏和豎屏都是執行一次,而並非這里說的有執行兩次的情況);
2、設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次;
3、設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執行onConfigurationChanged方法。
註:上述描述是在Android3.2以前,如果缺少了keyboardHidden選項,不能防止Activity的銷毀重啟,也就不能執行onConfigurationChanged方法了。在3.2之後,必須加上screenSize屬性才可以屏蔽調用Activity的生命周期(一些設備上可以不需要keyboardHidden,只要screenSize就可以了,保守起見還是繼續保留keyboardHidden吧)。
Ⅵ android:configChanges="orientation 生命周期問題
android:configChanges="orientation" 配置後,該事件被中悉你接收基山了,如賣鋒乎果你沒有處理這個事件就被丟棄了,
如果沒有配置,系統會接收這個事件,然後會重新啟動你的應用程序,
Ⅶ Activity橫豎屏切換生命周期變化
onCreate ,
創建activity時調用。設置在該方法中,還以Bundle中可以提出用於創建該 Activity 所需的信息。
onStart ,
activity變為在屏幕上對用戶可見時,即獲得焦點時,會調用。
onResume ,
activity開始與用戶交互時調用(無論是啟動還是重新啟動一個活動,該方法總是被調用的)
onSaveInstanceState
onPause ,
activity被暫停或收回cpu和其他資源時調用,該方法用於保存活動狀態的
onStop ,
activity被停止並轉為不可見階段及後續的生命周期事件時,即失去焦點時調用
onDestroy ,
activity被完全從系統內存中移除時調用,該方法被調用可能是因為有人直接調用 finish()方法 或者系統決定停止該活動以釋放資源。
onRestoreInstanceState ,
Android在橫豎排切換時候,將主動銷毀activity和重新創建一個新的activity出來,在此過程中,onRestoreInstanceState就要被回調
onConfigurationChanged ,
配置指定屬性後,屏幕方向發生變化後回調此函數.
把該Activity添加
android:configChanges="orientation" ,
執行步驟3(切換成橫屏時)
android:configChanges="orientation" 對於4.04.0以上版本不生效
把該Activity添加 android:configChanges="orientation|screenSize" ,
執行步驟3(切換成橫屏時)
onConfigurationChanged-->
只列印onConfigChanged
把 android:configChanges="orientation|screenSize" 改成 android:configChanges="orientation|keyboardHidden|screenSize"
執行步驟3(切換橫屏幕)
只列印
onConfigChanged
執行步驟4(切換豎屏幕)
只列印onConfigChanged
切記一定要加上後邊的screenSize否則在4.0以上版本生命周期執行不生效。
當前Activity產生事件彈出Toast和AlertDialog的時候Activity的生命周期不會有改變
Activity運行時按下HOME鍵(跟被完全覆蓋是一樣的):
onPause --> onStop onRestart -->onStart--->onResume
Activity未被完全覆蓋只是失去焦點:onPause--->onResume
測試用手機版本5.1.1
Android實現屏幕旋轉方法
這種方法的優點:即使屏幕旋轉,Activity也不會重新onCreate。
缺點:屏幕只有一個方向。
這個方法的優點:我們可以隨時監聽屏幕旋轉變化,並對應做出相應的操作;
缺點:它只能一次旋轉90度,如果一下子旋轉180度,onConfigurationChanged函數不會被調用。
4.設置方向的其他方式
在AndroidManifest.xml設置
橫向顯示,但是基於設備感測器,既可以是按正常方向顯示,也可以反向顯示,在API Level 9中被引入。
android:screenOrientation="sensorLandscape"
縱向顯示,但是基於設備感測器,既可以是按正常方向顯示,也可以反向顯示,在API Level 9中被引入。
android:screenOrientation="sensorLandscape"
demo
Ⅷ 面試題:Activity橫豎屏切換時的生命周期如何變化
看視頻時經常用到橫豎屏切換時,你有沒有了解過,這時候的activity生命周期如何變換?切換橫豎屏監聽變化需要用到activity的屬性:configChanges屬性,用於監聽屏幕的橫豎屏切換事件。
android:configChanges,用於捕獲手機狀態的改變,當橫豎屏切換,屏幕尺寸變化,彈出鍵盤,系統設置改變等條件,就會觸發回調事件onConfigurationChanged。
mcc:移動國家號碼,由三位數字組成,每個國家都有自己獨立的MCC,可以識別手機用戶所屬國家;
mnc:移動網號,在一派型盯個國家或者地區中,用於區分手機用戶的服務商;
locale:用戶所在塵和地區發生變化;
touchscreen:觸摸屏幕變化;
keyboard:鍵盤模式發生變化,例如:用戶接入外部鍵盤輸入;
keyboardHidden:用戶打開手機硬體鍵盤;
navigation:導航類型改變;
orientation:設備旋轉,橫向顯示和豎向顯示模式切換;
fontScale:全局字體大小縮放發生改變。
我這個activity不是main所以不設置<intent-filter>屬性,如果是首發,其他不用修改,加上android:configChanges="orientation|keyboard|layoutDirection|screenSize">即可。
此時屬於第四種結果,無法在logcat中顯示生命周期變化情況,只執行重寫的onConfigurationChanged方法。
剛開始豎屏調用方法順序:
==>>onStart()
==>>onResume()
變為橫屏時的生命周期變化:
==>>onPause()
==>>onStop()
==>>onDestory() //調用完整生命周期一次
==>>onStart()
==>>onResume()
重新變為豎屏時的生命周期變化:
==>>租告onPause()
==>>onStop()
==>>onDestory() //調用完整生命周期二次
==>>onStart()
==>>onResume()
退出activity時生命周期變化:
==>>onPause()
==>>onStop()
==>>onDestory() //調用完整生命周期三次
總結:橫屏調用完整生命周期一次,豎屏調用兩次。
總結:也是橫屏調用完整生命周期1次,豎屏調用2次。
總結:也是橫屏調用完整生命周期1次,豎屏調用2次。
總結:橫豎屏切換時不會調用各個生命周期方法。只會執行onConfigurationChanged方法,彈出Toast消息提示用戶。
Ⅸ Android的 MySurfaceView 的橫 豎屏切換問題
一、禁止橫豎屏轉換
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"); // 橫屏
} 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不延續上述的重建流程。在Android工程的Mainfest.xml中配置Activity:android:configChanges="keyboardHidden|orientation",橫豎屏切換之後就不會去執行OnCreat函數了,而是會去調用onConfigurationChanged()這樣就能控制橫豎屏的切換了。用戶可以在Activity或View的onConfigurationChanged(Configuration newConfig)函數中獲取當前橫豎屏參數。至於其調用順序跟touch時間的傳遞順序相似,不過他沒有消費事件的概念,會順次調用到每一個onConfigurationChanged函數。
需要重寫Activity的onConfigurationChanged方法。實現方式如下,不需要做太多的內容:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
// land do nothing is ok
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// port do nothing 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
public void 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方法
Ⅹ 橫豎屏切換時activity走哪幾個生命周期
Activity 生命周期 1.啟動伏李搭Activity onCreate() -> onStart() -> onResume() 此時進入運行狀態 2.鎖屏或者被其他Activity覆蓋缺拿時 onPause() 此時進入擾哪停止狀態 3.回到Activity onResume() 4.按Home鍵 onPause() -> onStop() 5.回到Activity onResta...