當螢幕方向改變時,我們通常會在Activity中Override function : onConfigurationChanged 的方式來接收變化。
但目前只有當 Landscape 與 Portrait 之間互轉時才會收到event.
所以landscape轉成reverse landscape並不會由onConfigurationChanged收到變化.
onConfigurationChanged
onConfigurationChanged接收orientation變化的方式如下
在AndroidManifest.xml的填入android:configChanges
AndroidManifest.xml1 2 3 4 5 6
| <application ... > <activity android:name=".MainActivity" android:screenOrientation="sensorLandscape" android:configChanges="orientation|screenSize|keyboardHidden"/> </application>
|
在MainActivity.java中增加Override function : onConfigurationChanged 。
AndroidManifest.xml1 2 3
| override fun onConfigurationChanged(newConfig: Configuration?) { super.onConfigurationChanged(newConfig) }
|
以上的方式無法得知 landscape轉成reverse landscape的訊息。
我們可監聽Ratation的變化來實現此功能。
Rotation Changed Listener
Step 1: 建立callback : RotationCallback
新增kotlin interface : RotationCallback
RotationCallback.kt1 2 3
| interface RotationCallback { fun onRotationChanged(lastRotation: Int, newRotation: Int) }
|
Step 2: 建立Listerner : RotationListener
新增kotlin class : RotationListener
其中mOrientationEventListener監聽Rotation的變化,並透過mCallback傳遞給上層
RotationListener.kt1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class RotationListener { private var mOrientationEventListener: OrientationEventListener? = null private var mCallback: RotationCallback? = null
private var lastRotation: Int = 0
constructor(callback: RotationCallback) { mCallback = callback }
fun listen(context: Context) { mOrientationEventListener = object : OrientationEventListener(context, SensorManager.SENSOR_DELAY_NORMAL) { override fun onOrientationChanged(orientation: Int) { val localWindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager if (null != localWindowManager && null != mCallback) { val newRotation = localWindowManager.defaultDisplay.rotation if (newRotation != lastRotation) { mCallback!!.onRotationChanged(lastRotation, newRotation) lastRotation = newRotation } } } } mOrientationEventListener!!.enable()
lastRotation = (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay.rotation }
fun stop() { if (null != mOrientationEventListener) { mOrientationEventListener!!.disable() } mOrientationEventListener = null mCallback = null } }
|
Step 3: MainActivity監聽與解除接聽
MainActivity繼承RotationCallback且實現其onRotationChanged function,並在onCreate時建立監聽Rotation變化, 而在onDestroy時取消監聽
MainActivity.kt1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class MainActivity : AppCompatActivity(), RotationCallback { private val TAG = "MainActivity " private var mRotationListener : RotationListener? = null
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mRotationListener = RotationListener(this) mRotationListener!!.listen(this.applicationContext) } override fun onDestroy() { super.onDestroy() Log.e(TAG, "onDestroy()") mRotationListener!!.stop() mRotationListener = null }
override fun onRotationChanged(lastRotation: Int, newRotation: Int) { Log.d(TAG, "onRotationChanged: last " + (lastRotation) +" new " + (newRotation)); } }
|
這樣就可以得知landscape與reverse landscape的變化了。