Android 화면 회전 감청 방법

배경
개인 에 대해 서 는 얼마 전에 업무 가 너무 바 빠 서 생각 도 못 하고 침전 시 켰 습 니 다.이 동시에 팀 내 에서 모두 업무 에 있어 자신의 사고 와 정 리 를 할 수 있다.이런 분위기 에서 자신 도 모 르 게 주말 에 글 을 쓰기 시작 하 게 한다.자신 이 일상 업무 에 바 쁜 것 을 제외 하고 뭔 가 를 침전 시 키 고 자신의 성장 을 더 할 수 있 기 를 바란다.
착안점 에 대해 최근 에 이 야 기 를 할 때 스크린 회전 사건 을 감청 하여 현탁 구 의 위 치 를 조정 해 야 한다.일부 상황 에서 시스템 리 셋 을 받 지 못 하고 넘 어 지 는 것 을 생각 하 며 화면 회전 에 대한 모 의 감청 을 했 는데 대체적으로 12140℃에 달 할 수 있다.
문제.
부상 구 는 멈 추고 드래그 한 후,⼿机 화면의 좌우 양쪽 에 붙 여야 한다.
세로 화면 상태 에서 x 좌 표 는 0 즉 왼쪽 가장자리 이 고 x 좌 표 는 화면 너비 즉 오른쪽 가장자리 이다.
그러나 가로 화면 상태 에서 상황 은 비교적 복잡 하 다.현재⼤부분 안 드 로 이 드⼿기 는 모두 앞머리 스크린 의 디자인 으로 전체 화면 상태 에서 플 로 팅 볼 을 옆 에 붙 일 때 앞머리 에서⾯를 받 을 수 없다.그렇지 않 으 면 눌 러 지지 않 는 다.
그래서 이때 앞머리 의 너 비 를 계산 하고 이 너 비 를 부상 구 왼쪽 의 시작 위치 로 해 야 한다.그러면 부상 구가 옆 에 붙 을 때 앞머리 밑 으로 숨 지 않 는 다.아래 그림 과 같다.

그러나 화면 이 회전 한 후에 앞 머리 는 오른쪽 에 이 르 렀 고 왼쪽 은 앞머리 의 너 비 를 현탁 구 의 출발점 으로 해 서 는 안 된다.이렇게 되면 모니터 의 회전 을 감청 해 야 합 니 다.모니터 의 방향 에 맞 춰 11974℃로 정확하게 판단 할 수 있 습 니 다.모니터 의 회전 은 Activity 의 onConfiguration Changed⽣수명 주 기 를 다시 쓰기 만 하면 됩 니 다.

override fun onConfigurationChanged(newConfig: Configuration) {
 super.onConfigurationChanged(newConfig)
 Log.i(TAG, "on configuration changed")
}
AndroidManifest 에 설정

android:configChanges="orientation|screenSize"
이때 문 제 를 발 견 했 습 니 다.Activity 의 screenOrientation 을 sensor Landscape 로 설정 할 때 화면 이 회전 하 더 라 도 이 반전 을 받 지 못 합 니 다(이것 은 이전의 이해 와 약간 다 릅 니 다).그래서 screenOrientation 을 sensor 로 설정 하면 화면 이 회전 하면 정상적으로 이⾥로 되 돌 릴 수 있 습 니 다.여러 번 시도 해 보 니 가로 화면 과 세로 화면 사 이 를 전환 할 때 만 리 셋 을 받 을 수 있 습 니 다.가로 화면 을 직접 거꾸로 하면 가로 화면 상태 가 변 하지 않 고⽅방향 으로 바 뀌 어야 이때 도 리 셋 을 받 지 못 합 니 다.
해결 방향
onConfiguration Changed 가 리 셋 을 받 지 못 하 는 이상 다른 방법 도 있 습 니 다.바로 화면 을 감청 하 는 것 입 니 다.코드 는 다음 과 같 습 니 다.

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
 }
 }
}
앞 머리 는 왼쪽 인지 오른쪽 인지 도수 로 판단 한다.즉 270 도 는 왼쪽,90 도 는 오른쪽 이다.이런⽅式 은 문 제 를 해결 할 수 있 을 것 같 지만 많이 회전 하면⼏에 다른 문제 가 있 음 을 발견 할 수 있다.정상 적 인 사고 에 따 르 면 화면의 디 스 플레이 는 이 도수 와 일치 해 야 한다.즉,화면의 디 스 플레이 는 위 에서 아래로 내 려 가 야 한다.하지만 다음 그림 은 그렇지 않다.

이때 도 수 는 90 인 데 화면 이 거꾸로 표 시 된 것 은 정⽴상태 로 회전 하지 않 았 다.그러나 상⾯코드 에 따라 90 도 를 정상 90 도 정⽴상태 로 판정 하 는데 이때 부상 구 의 위 치 를 수정 하 는 것 은 잘못된 것 이다.
그러면 onOrientationChanged 라 는 리 셋 을 받 았 을 때 화면 에 표 시 된 방향 을 판단 할 수 있다 면,도수 가 90 도 범위 에 이 르 렀 을 때 화면의 방향 을 동시에 판단 하 는 것 입 니 다.즉,두 가지 조건 이 동시에 꽉 차 야 화면 회전 으로 판 정 됩 니 다.
스토리 보드 의 코드 판정 화면 표시 방향

val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as
WindowManager
val rotation = windowManager.defaultDisplay?.rotation
//rotation   0、1、2、3,           
이러한 판단 을 통 해 기본적으로 스크린 회전 사건 을 정확하게 감청 할 수 있 습 니 다.onOrientationChanged 라 는 리 셋 은 매우 민감 합 니 다.그럼 저 는 정상 적 인 화면 회전 사건 을 모 의 해서 현탁 구 의 위 치 를 수정 하고 싶 습 니 다.자주 갱신 할 수 는 없 잖 아 요.이것 은 12197 년 에 제 어 를 하면 됩 니 다.모든 코드 는 다음 과 같 습 니 다.

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)
 }
}
스토리 보드 를 쓰 면 바로 이렇게:

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 -> {}
  }
 }
})
위의 코드 를 통 해 onOrientationChanged 가 90 도 범위 내 에서 화면 표시 방향 이 Surface.ROTATION 인 것 으로 판 정 됩 니 다.270⽐비교,⽽270 범위 내 시 는 Surface.ROTATION90 은 비교 했다.\11974°도 는 시계 방향 으로 점점 증가 하 는 것 을 알 수 있 습 니 다.⽽화면 방향 은 시계 반대 방향 으로 도 수 를 계산 합 니 다.
기타 문제
테스트 과정 에서 위 에 있 는 안건 은 또 다른 문제 가 존재 합 니 다.onOrientation Changed 라 는 리 셋 이 매우 민감 하지만 도수 가 변 하지 않 습 니 다.화면 이 회전 하 는 상황 에서 도 발생 합 니 다.즉,화면 방향 이 변 하지 않 습 니 다.즉,화면의 경사 가 증가 하 는 것 입 니 다.이때 onOrientationChanged 는 변 함 이 없 기 때문에 반전 되 지 않 습 니 다.이렇게 하면 화면 이 회전 하 는 반전 을 받 을 수 없 지만 실제 스토리 보드 장면 에서 이런 상황 은 12112℃가 적 으 니 직접 해 볼 수 있다.
작은 매듭
평소에 개발 할 때 어떤 상태 로 가로 화면 을 하 는 장면 이 비교적 적은 지 구분 해 야 한다.그렇지 않 으 면 안 드 로 이 드 가 정확 한 리 셋 을 해 줄 것 이 라 고 생각한다.안 드 로 이 드 장치 가 심하게 깨 졌 습 니 다.앞 머리 를 제외 하고 화면의 아래 가장자리 에 가상 네 비게 이 션 표시 줄 이 있 습 니 다.서로 다른 시스템 설정 에서 이 네 비게 이 션 표시 줄 은 상 태 를 표시 하지 않 으 면 모양 이 보이 지 않 습 니 다.그렇다면 이때 플 로 팅 볼 에 옆 구 리 를 붙 이 는 수요 에 서 는 앞머리 뿐만 아니 라 내 비게 이 션 도 고려 해 야 한다.더욱 심 한 것 은 회전 하 는 과정 에서 가상 네 비게 이 션 바 는 12032℃에서 계속 유지 되 고 앞머리 와 중첩 된다.그러면 위 치 를 정확히 계산 해 야 한다.첫 번 째 단 계 는 화면의 회전 을 감청 하 는 것 이다.
이상 은 안 드 로 이 드 화면 회전 을 어떻게 감청 하 는 지 에 대한 상세 한 내용 입 니 다.안 드 로 이 드 화면 회전 을 감청 하 는 자 료 는 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기