Android屏幕旋轉(zhuǎn)之橫屏豎屏切換的實(shí)現(xiàn)
剛實(shí)現(xiàn)了App內(nèi)手機(jī)橫/豎放置時(shí),屏幕橫/豎屏的切換。記錄一下中間需要的關(guān)鍵信息和實(shí)現(xiàn)過(guò)程。
開(kāi)門(mén)見(jiàn)山的說(shuō),實(shí)現(xiàn)屏幕自動(dòng)/手動(dòng)旋轉(zhuǎn)的方式有兩種:
一種是在工程的代碼中定義,這種方式在橫豎屏切換時(shí)執(zhí)行的操作是:銷毀當(dāng)前Activity–根據(jù)新的屏幕尺寸重建Activity。如果不進(jìn)行數(shù)據(jù)存儲(chǔ)的操作,在切換的過(guò)程中Activity中的數(shù)據(jù)會(huì)丟失。
另一種是在工程的AndroidManifest.xml中定義,這種定義的方式在某些情況下可以實(shí)現(xiàn)“不銷毀需要橫豎屏的Activity”,因?yàn)檫@種方式不會(huì)銷毀Activity后重建Activity,因此Activity的數(shù)據(jù)不會(huì)丟失。
接下來(lái)分別介紹這兩種實(shí)現(xiàn)方式:
方式一:代碼中定義
在需要橫屏的Activity中的onCreate方法內(nèi)添加如下語(yǔ)句,并且要求該語(yǔ)句位于onCreate方法內(nèi)setContentView(**)語(yǔ)句之前。
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
上條語(yǔ)句中,常數(shù)SCREEN_ORIENTATION_FULL_SENSOR是決定屏幕如何旋轉(zhuǎn)的參數(shù)??偨Y(jié)所有的參數(shù)對(duì)應(yīng)的功能:
| 參數(shù) | 功能 |
|---|---|
| SCREEN_ORIENTATION_BEHIND | 繼承Activity堆棧中當(dāng)前Activity下面的那個(gè)Activity的方向 |
| SCREEN_ORIENTATION_FULL_SENSOR | 由重力傳感器決定0/90/180/270° |
| SCREEN_ORIENTATION_FULL_USER | |
| SCREEN_ORIENTATION_LANDSCAPE | 始終橫屏 |
| SCREEN_ORIENTATION_PORTRAIT | 始終豎屏 |
| SCREEN_ORIENTATION_LOCKED | 鎖定屏幕方向 |
| SCREEN_ORIENTATION_NOSENSOR | 關(guān)閉重力傳感器對(duì)橫/豎屏的影響 |
| SCREEN_ORIENTATION_REVERSE_LANDSCAPE | 另一個(gè)方向的橫屏 |
| SCREEN_ORIENTATION_REVERSE_PORTRAIT | 另一個(gè)方向的豎屏(倒拿手機(jī)) |
| SCREEN_ORIENTATION_SENSOR | 重力傳感器影響屏幕的方向0/90/270° |
| SCREEN_ORIENTATION_SENSOR_LANDSCAPE | 始終橫屏,由重力傳感器決定是哪個(gè)方向的橫屏 |
| SCREEN_ORIENTATION_SENSOR_PORTRAIT | 始終豎屏,由重力傳感器決定是哪個(gè)方向的豎屏 |
| SCREEN_ORIENTATION_UNSPECIFIED | 不指定方向,使用默認(rèn)方向 |
| SCREEN_ORIENTATION_USER | 由用戶和重力傳感器共同決定,詳見(jiàn)文本末端 |
| SCREEN_ORIENTATION_USER_LANDSCAPE | 用戶和重力傳感器共同決定是哪個(gè)方向的橫屏 |
| SCREEN_ORIENTATION_USER_PORTRAIT | 用戶和重力傳感器共同決定是哪個(gè)方向的豎屏 |
| UIOPTION_SPLIT_ACTION_BAR_WHEN_NARROW | 當(dāng)屏幕較窄時(shí)導(dǎo)航欄有一部分會(huì)顯示在底部 |
由于該方式下橫/豎屏切換時(shí),對(duì)應(yīng)的Activity的數(shù)據(jù)會(huì)丟失,可以在對(duì)應(yīng)的Activity中重寫(xiě)如下兩個(gè)方法,來(lái)保證數(shù)據(jù)不丟失:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//橫豎屏切換前調(diào)用,保存用戶想要保存的數(shù)據(jù),以下是樣例
outState.putString("name","yoosir");
outState.putInt("age",24);
outState.putBoolean("handsome",true);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// 屏幕切換完畢后調(diào)用用戶存儲(chǔ)的數(shù)據(jù),以下為樣例:
if(savedInstanceState != null) {
int age = savedInstanceState.getInt("age");
String name = savedInstanceState.getString("name");
boolean isHandsome = savedInstanceState.getBoolean("handsome");
}
}
方式二:在AndroidManifest.xml中定義
在AndroidManifest.xml中對(duì)應(yīng)的Activity屬性定義中配置android:configChanges和screenOrientation。參考的文章中在android:configChanges的配置說(shuō)的很清楚,我直接把結(jié)論貼出來(lái):
android:configChanges="orientation|keyboardHidden|screenSize"
- 配置configChanges為以上配置時(shí),切屏不會(huì)重新調(diào)用各個(gè)生命周期,只會(huì)執(zhí)行onConfigurationChanged方法。Activity中的數(shù)據(jù)不會(huì)被銷毀。
- 不配置configChanges或配置configChanges為非以上配置時(shí),切屏?xí)匦抡{(diào)用當(dāng)前Activity的各個(gè)生命周期。Activity中的數(shù)據(jù)會(huì)被銷毀。
給出示例代碼如下:
<activity android:name=".com.cdsn.SearchActivity"
... ...
android:screenOrientation="sensor"
android:configChanges="keyboardHidden|orientation|screenSize"
/>
上述代碼中的android:screenOrientation所有可能的參數(shù)配置如下 。
| 值 | 描述 |
|---|---|
| unspecified | 默認(rèn)值。系統(tǒng)自動(dòng)選擇屏幕方向 |
| behind | 跟activity堆棧中的下面一個(gè)activity的方向一致 |
| landscape | 橫屏方向,顯示的寬比高長(zhǎng) |
| portrait | 豎屏方向,顯示的高比寬長(zhǎng) |
| sensor | 由設(shè)備的物理方向傳感器決定,如果用戶旋轉(zhuǎn)設(shè)備,這屏幕就會(huì)橫豎屏切換 |
| nosensor | 忽略物理方向傳感器,這樣就不會(huì)隨著用戶旋轉(zhuǎn)設(shè)備而橫豎屏切換了(”unspecified”設(shè)置除外) |
| user | 用戶當(dāng)前首選的方向 |
| reverseLandscape | API 9 以上,反向橫屏 |
| reversePortrait | API 9 以上,反向豎屏 |
| sensorLandscape | API 9 以上,橫屏,但是可以根據(jù) 物理方向傳感器來(lái)切換正反向橫屏 |
| sensorPortrait | API 9 以上,豎屏,但是可以根據(jù) 物理方向傳感器來(lái)切換正反向豎屏 |
| fullSensor | API 9 以上,上下左右四個(gè)方向,由物理方向傳感器決定 |
| locked | API 18 以上,鎖死當(dāng)前屏幕的方向 |
上述代碼中的android:configChanges所有可能的參數(shù)配置如下:
| 值 | 描述 |
|---|---|
| mcc | IMSI移動(dòng)臺(tái)的國(guó)家代碼(MCC)發(fā)生變化——一個(gè)SIM被探測(cè)到并且更新MCC |
| mnc | IMSI移動(dòng)臺(tái)的網(wǎng)絡(luò)代碼(MNC)發(fā)生變化——一個(gè)SIM被探測(cè)到并且更新MNC |
| locale | 區(qū)域發(fā)生變化——用戶選擇了一個(gè)文本需要顯示的新語(yǔ)言 |
| keyboard | 鍵盤(pán)類型發(fā)生變化——例如:用戶插入了外接鍵盤(pán)。 |
| keyboardHidden | 鍵盤(pán)的可訪問(wèn)性發(fā)生變化——例如:用戶發(fā)現(xiàn)了硬件鍵盤(pán)。 |
| screenLayout | 屏幕布局發(fā)生變化——這個(gè)會(huì)導(dǎo)致顯示不同的Activity。 |
| orientation | 屏幕方向發(fā)生變化——用戶旋轉(zhuǎn)了屏幕。注意:如果應(yīng)用程序的目標(biāo)API級(jí)別是13或更高(通過(guò)屬性minSdkVersion和屬性targetSdkVersion聲明),你也需要聲明配置項(xiàng)screenSize,因?yàn)檫@將在設(shè)備選擇肖像和屏幕方向時(shí)發(fā)生改變。 |
| screenSize | 當(dāng)前可用屏幕大小發(fā)生變化。這代表一個(gè)當(dāng)前可用大小的變化,和當(dāng)前的比率相關(guān),因此當(dāng)用戶選擇不同的畫(huà)面和圖像,會(huì)發(fā)生變化。然而,如果你的程序目標(biāo)API級(jí)別是12或更低,你的Activity總是會(huì)自己處理這個(gè)配置變化(這個(gè)變化不會(huì)引起Activity的重啟,甚至在Android 3.2或更新的設(shè)備上)。在API級(jí)別13里加入的。 |
| smallestScreenSize | 物理屏幕大小的變化。不管方向的變化,僅僅在實(shí)際物理屏幕打包變化的時(shí)候,如:外接顯示器。這個(gè)配置項(xiàng)的變化引起在smallestWidth configuration里的變化。然而,如果你的程序目標(biāo)API級(jí)別是12或更低,你的Activity將自己處理這個(gè)變化(這個(gè)變化不會(huì)引起Activity的重啟,甚至在Android 3.2或更新的設(shè)備上)在API級(jí)別13里加入的。 |
| layoutDirection | 布局方向變化。例如書(shū)寫(xiě)方式從左向右(LTR)轉(zhuǎn)換為從右向左(RTL) |
配置了以上屬性之后,進(jìn)行橫豎屏切換的Activity的數(shù)據(jù)不會(huì)丟失,如果想根據(jù)不同的屏幕方向來(lái)展示不同UI或做不同的事,需要在該Activity中重寫(xiě)以下方法:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// 在這里添加屏幕切換后的操作
}
番外
我按照上述方法,根據(jù)重力傳感器實(shí)現(xiàn)了屏幕旋轉(zhuǎn),雖然可以做到屏幕隨重力傳感器切換,但是發(fā)現(xiàn):無(wú)論手機(jī)設(shè)置中“屏幕旋轉(zhuǎn)”或“方向鎖定”是開(kāi)是關(guān),App內(nèi)的Activity都會(huì)隨著手機(jī)的橫豎方向切換橫豎屏。我想要實(shí)現(xiàn)的是當(dāng)打開(kāi)“屏幕旋轉(zhuǎn)”時(shí),App內(nèi)的Activity跟隨重力感應(yīng)器;當(dāng)關(guān)閉“屏幕旋轉(zhuǎn)”時(shí),App內(nèi)的Activity固定為默認(rèn)方向。如何做到關(guān)閉重力傳感器時(shí),App亦關(guān)閉屏幕自動(dòng)旋轉(zhuǎn)?
android:screenOrientation="sensor"
改上述代碼為以下代碼
android:screenOrientation="user"
意即:當(dāng)參數(shù)為sensor時(shí),無(wú)論是否關(guān)閉“屏幕旋轉(zhuǎn)”設(shè)置,App內(nèi)的特定Activity都會(huì)根據(jù)重力傳感器改變橫豎屏。
當(dāng)參數(shù)為user時(shí),當(dāng)“屏幕旋轉(zhuǎn)”開(kāi)啟,則特定Activity根據(jù)根據(jù)重力傳感器改變橫豎屏;當(dāng)“屏幕旋轉(zhuǎn)”關(guān)閉,則特定Activity會(huì)固定位默認(rèn)方向(一般為正面豎屏)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實(shí)現(xiàn)屏幕旋轉(zhuǎn)四個(gè)方向準(zhǔn)確監(jiān)聽(tīng)
- Android如何監(jiān)聽(tīng)屏幕旋轉(zhuǎn)
- Android6.0開(kāi)發(fā)中屏幕旋轉(zhuǎn)原理與流程分析
- Android webview旋轉(zhuǎn)屏幕導(dǎo)致頁(yè)面重新加載問(wèn)題解決辦法
- Android屏幕旋轉(zhuǎn) 處理Activity與AsyncTask的最佳解決方案
- 詳解Android中Runtime解決屏幕旋轉(zhuǎn)問(wèn)題(推薦)
- Android實(shí)現(xiàn)屏幕旋轉(zhuǎn)方法總結(jié)
- Android開(kāi)發(fā) 旋轉(zhuǎn)屏幕導(dǎo)致Activity重建解決方法
- Android實(shí)現(xiàn)簡(jiǎn)單旋轉(zhuǎn)動(dòng)畫(huà)
- Android App獲取屏幕旋轉(zhuǎn)角度的方法
相關(guān)文章
Android App開(kāi)發(fā)的自動(dòng)化測(cè)試框架UI Automator使用教程
UI Automator為Android程序的UI開(kāi)發(fā)提供了測(cè)試環(huán)境,這里我們就來(lái)看一下Android App開(kāi)發(fā)的自動(dòng)化測(cè)試框架UI Automator使用教程,需要的朋友可以參考下2016-07-07
Android數(shù)據(jù)加密之異或加密算法的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇Android數(shù)據(jù)加密之異或加密算法的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10
Android AccessibilityService實(shí)現(xiàn)微信搶紅包插件
這篇文章主要介紹了Android AccessibilityService實(shí)現(xiàn)微信搶紅包插件的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android系統(tǒng)優(yōu)化Ninja加快編譯
這篇文章主要為大家介紹了Android系統(tǒng)優(yōu)化使用Ninja加快編譯示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Dcloud的native.js直接撥打電話Android實(shí)例代碼
本文為大家分享了3種利用Dcloud的native.js直接撥打電話實(shí)例代碼,由于iOS系統(tǒng)的限制所以只有Android版實(shí)例2018-09-09
Android實(shí)現(xiàn)網(wǎng)絡(luò)圖片瀏覽功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)網(wǎng)絡(luò)圖片瀏覽功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
android10 隱藏SystemUI鎖屏下的多用戶圖標(biāo)的示例代碼
這篇文章主要介紹了android10 隱藏SystemUI鎖屏下的多用戶圖標(biāo),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12

