您好,登錄后才能下訂單哦!
這篇文章主要介紹Android怎么監(jiān)聽(tīng)屏幕旋轉(zhuǎn),文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
關(guān)于個(gè)人,前段時(shí)間由于業(yè)務(wù)太忙,所以一直沒(méi)有來(lái)得及思考并且沉淀點(diǎn)東西;同時(shí)組內(nèi)一個(gè)個(gè)都在業(yè)務(wù)上能有自己的思考和總結(jié),在這樣的氛圍下,不由自主的驅(qū)使周末開(kāi)始寫(xiě)點(diǎn)東西,希望自己除了日常忙于業(yè)務(wù),可以沉淀點(diǎn)東西,加上自己的成長(zhǎng)..
關(guān)于切入點(diǎn),最近在做應(yīng)?內(nèi)懸浮球功能時(shí),需要監(jiān)聽(tīng)屏幕旋轉(zhuǎn)事件來(lái)對(duì)懸浮球的位置進(jìn)?調(diào)整,發(fā)現(xiàn)有些情況下并不能收到系統(tǒng)回調(diào),思考了?翻,做了?個(gè)屏幕旋轉(zhuǎn)的模擬監(jiān)聽(tīng),基本上能達(dá)到?的。
懸浮球在停?拖拽后,需要貼邊到?機(jī)屏幕的左右兩側(cè)。
在豎屏狀態(tài)下,x坐標(biāo)為0即為左邊緣,x坐 標(biāo)為屏幕寬度即為右邊緣。
但是在橫屏狀態(tài)下,情況就?較復(fù)雜了?,F(xiàn)在?部分Android?機(jī)都是劉 海屏的設(shè)計(jì),在全屏狀態(tài)下,懸浮球貼邊時(shí)不能收到劉海下?去,不然就點(diǎn)不到了。
所以此時(shí)需要算 出劉海的寬度,以此寬度作為懸浮球左邊的起始位置,這樣懸浮球貼邊的時(shí)候就不會(huì)躲到劉海下? 去。 如下圖所示
但是在屏幕旋轉(zhuǎn)之后,劉海到了右邊,左邊就不應(yīng)該以劉海的寬度作為懸浮球的起點(diǎn)了。 這樣的話(huà)就需要監(jiān)聽(tīng)屏幕的旋轉(zhuǎn)了,配合屏幕?向的?度,就能正確判斷。監(jiān)聽(tīng)屏幕的旋轉(zhuǎn)只需要重 寫(xiě)Activity的onConfiguratuonChanged?命周期。
override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) Log.i(TAG, "on configuration changed") }
在AndroidManifest中配置
android:configChanges="orientation|screenSize"
此時(shí)發(fā)現(xiàn)了?個(gè)問(wèn)題,當(dāng)把Activity的screenOrientation設(shè)置成sensorLandscape時(shí),即使屏幕旋轉(zhuǎn) 也收不到這個(gè)回調(diào)(這個(gè)和之前的理解有點(diǎn)不?樣)。于是將screenOrientation設(shè)置成sensor,屏 幕旋轉(zhuǎn)就能正?;卣{(diào)到這?,多試?次發(fā)現(xiàn),只有在橫屏和豎屏之間切換時(shí)才能收到回調(diào),如果直接 將橫屏倒過(guò)來(lái),就是橫屏狀態(tài)不變,?向調(diào)轉(zhuǎn),此時(shí)也不會(huì)收到回調(diào)。
既然onConfigurationChanged收不到回調(diào),還有另外?個(gè)辦法,就是監(jiān)聽(tīng)屏幕?向度數(shù),代碼如下
mOrientationEventListener = object : OrientationEventListener(this) { override fun onOrientationChanged(orientation: Int) { Log.i(TAG, "on orientation changed angle is $orientation") if (orientation > 340 || orientation < 20) { //0 } else if (orientation in 71..109) { //90 } else if (orientation in 161..199) { //180 } else if (orientation in 251..289) { //270 } } }
通過(guò)度數(shù)來(lái)判斷劉海是在左邊還是在右邊,即270度時(shí)在左邊,90度時(shí)在右邊。這種?式看起來(lái)可以 解決問(wèn)題,但是多旋轉(zhuǎn)?次就發(fā)現(xiàn)?有其他問(wèn)題。按照正常思維,屏幕的顯示?向應(yīng)該和這個(gè)度數(shù)? 致才對(duì),即屏幕的顯示應(yīng)該是?上?下的。但是下圖就不是這樣。
此時(shí)度數(shù)為90,屏幕卻倒?著顯示的,并沒(méi)有旋轉(zhuǎn)成正?狀態(tài),但是按照上?的代碼,會(huì)將90度判定 為正常90度正?顯示的狀態(tài),此時(shí)去修改懸浮球的位置就是錯(cuò)誤的。
那如果在收到onOrientationChanged這個(gè)回調(diào)時(shí)能判斷?下屏幕顯示的?向呢,就是在度數(shù)達(dá)到90 度范圍時(shí),同時(shí)判斷屏幕的顯示?向,即兩個(gè)條件同時(shí)滿(mǎn)?才判定成屏幕旋轉(zhuǎn)了。
?下?的代碼判定屏幕顯示?向
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager val rotation = windowManager.defaultDisplay?.rotation //rotation為常量0、1、2、3,分別表示屏幕的四個(gè)?向
通過(guò)這樣的判斷基本上能將屏幕旋轉(zhuǎn)事件監(jiān)聽(tīng)準(zhǔn)確了,onOrientationChanged這個(gè)回調(diào)很靈敏,? 機(jī)屏幕稍微動(dòng)?下就會(huì)回調(diào)。那我希望模擬正常的屏幕旋轉(zhuǎn)事件來(lái)修改懸浮球的位置,總不能很頻繁 的刷新吧。這?做?下控制就好,全部代碼如下:
object ScreenOrientationHelper { val ORIENTATION_TYPE_0 = 0 val ORIENTATION_TYPE_90 = 90 val ORIENTATION_TYPE_180 = 180 val ORIENTATION_TYPE_270 = 270 private var mOrientationEventListener: OrientationEventListener? = null private var mScreenOrientationChangeListener: ScreenOrientationChangeListener? = null private var currentType = ORIENTATION_TYPE_0 fun init(context: Context, listener: ScreenOrientationChangeListener) { mScreenOrientationChangeListener = listener mOrientationEventListener = object : OrientationEventListener(context) { override fun onOrientationChanged(orientation: Int) { if (mScreenOrientationChangeListener == null) { return } if (orientation > 340 || orientation < 20) { //0 if (currentType == 0) { return } if (getScreenRotation(context) == Surface.ROTATION_0) { mScreenOrientationChangeListener!!.onChange(ORIENTATION_TYPE_0) currentType = ORIENTATION_TYPE_0 } } else if (orientation in 71..109) { //90 if (currentType == 90) { return } val angle = getScreenRotation(context) if (angle == Surface.ROTATION_270) { mScreenOrientationChangeListener!!.onChange(ORIENTATION_TYPE_90) currentType = ORIENTATION_TYPE_90 } } else if (orientation in 161..199) { //180 if (currentType == 180) { return } val angle = getScreenRotation(context) if (angle == Surface.ROTATION_180) { mScreenOrientationChangeListener!!.onChange(ORIENTATION_TYPE_180) currentType = ORIENTATION_TYPE_180 } } else if (orientation in 251..289) { //270 if (currentType == 270) { return } val angle = getScreenRotation(context) if (angle == Surface.ROTATION_90) { mScreenOrientationChangeListener!!.onChange(ORIENTATION_TYPE_270) currentType = ORIENTATION_TYPE_270 } } } } register() } private fun getScreenRotation(context: Context): Int { val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager return windowManager.defaultDisplay?.rotation ?: 0 } fun register() { if (mOrientationEventListener != null) { mOrientationEventListener!!.enable() } } fun unRegister() { if (mOrientationEventListener != null) { mOrientationEventListener!!.disable() } } interface ScreenOrientationChangeListener { /** * * @param orientation */ fun onChange(orientation: Int) } }
使?的話(huà),直接這樣:
ScreenOrientationHelper.init(this, object : ScreenOrientationHelper.ScreenOrientationChangeListener { override fun onChange(orientation: Int) { when(orientation) { ScreenOrientationHelper.ORIENTATION_TYPE_0 -> {} ScreenOrientationHelper.ORIENTATION_TYPE_90 -> {} ScreenOrientationHelper.ORIENTATION_TYPE_180 -> {} ScreenOrientationHelper.ORIENTATION_TYPE_270 -> {} } } })
通過(guò)上?的代碼發(fā)現(xiàn),在onOrientationChanged回調(diào)90度范圍內(nèi)時(shí),判定屏幕顯示?向是和 Surface.ROTATION_270?較的,?270范圍內(nèi)時(shí)是和Surface.ROTATION_90?較的??吹贸鰜?lái)?度 是順時(shí)針遞增的,?屏幕?向是逆時(shí)針計(jì)算度數(shù)的。
在測(cè)試過(guò)程中,上?的?案還存在另外?個(gè)問(wèn)題,雖然onOrientationChanged這個(gè)回調(diào)很靈敏,但 是也有度數(shù)不變?屏幕?向旋轉(zhuǎn)的情況發(fā)?,即保持屏幕?向不變,?是增加屏幕的坡度(將?機(jī)? 邊貼在桌?,慢慢?起來(lái)),在坡度達(dá)到?定時(shí),屏幕會(huì)發(fā)?旋轉(zhuǎn),此時(shí)onOrientationChanged是 不會(huì)回調(diào)的,因?yàn)闆](méi)有變化。這樣就收不到屏幕旋轉(zhuǎn)的回調(diào)了,但是在實(shí)際??機(jī)的場(chǎng)景中,這種情 況是?較少的,可以親身試試看。
以上是“Android怎么監(jiān)聽(tīng)屏幕旋轉(zhuǎn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。