我看到有几个类似的问题,但都没有答案。
从纵向旋转到横向(无论向哪个方向),然后再切换回来,我们会得到有用的onConfigurationChanged()调用。
然而,当在横向模式下旋转180度时,不会调用onConfigurationChanged()。
我看到了使用OrientationEventListener的提及,但我觉得这似乎不太可靠,因为你可以快速地旋转而不触发显示方向更改。
我尝试添加布局更改侦听器,但没有成功。
因此,问题是如何可靠地检测到这种横向方向的更改?
我看到有几个类似的问题,但都没有答案。
从纵向旋转到横向(无论向哪个方向),然后再切换回来,我们会得到有用的onConfigurationChanged()调用。
然而,当在横向模式下旋转180度时,不会调用onConfigurationChanged()。
我看到了使用OrientationEventListener的提及,但我觉得这似乎不太可靠,因为你可以快速地旋转而不触发显示方向更改。
我尝试添加布局更改侦听器,但没有成功。
因此,问题是如何可靠地检测到这种横向方向的更改?
当设备没有旋转/移动时,OrientationEventlistener不起作用。
我发现显示监听器是检测更改的更好方法。
DisplayManager.DisplayListener mDisplayListener = new DisplayManager.DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {
android.util.Log.i(TAG, "Display #" + displayId + " added.");
}
@Override
public void onDisplayChanged(int displayId) {
android.util.Log.i(TAG, "Display #" + displayId + " changed.");
}
@Override
public void onDisplayRemoved(int displayId) {
android.util.Log.i(TAG, "Display #" + displayId + " removed.");
}
};
DisplayManager displayManager = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
displayManager.registerDisplayListener(mDisplayListener, UIThreadHandler);
onDisplayChanged
仅在 getRotation()
更改时触发。 另一方面, OrientationEventListener
实时不断地触发,甚至在 getRotation()
更改之前就会触发,导致屏幕旋转值完全错误,当进行180度旋转时。 - 0101100101mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
OrientationEventListener orientationEventListener = new OrientationEventListener(this,
SensorManager.SENSOR_DELAY_NORMAL) {
@Override
public void onOrientationChanged(int orientation) {
Display display = mWindowManager.getDefaultDisplay();
int rotation = display.getRotation();
if ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) && rotation != mLastRotation) {
Log.i(TAG, "changed >>> " + rotation);
// do something
mLastRotation = rotation;
}
}
};
if (orientationEventListener.canDetectOrientation()) {
orientationEventListener.enable();
}
OrientationEventListener
不是适用于180°方向变化的正确工具,因为它会在实时中不断触发,甚至在getRotation()
改变之前就会触发!DisplayListener
做得更好,因为它只在getRotation()
改变时才会触发。 - 0101100101 OrientationEventListener mOrientationEventListener = new OrientationEventListener(mActivity)
{
@Override
public void onOrientationChanged(int orientation)
{
if (orientation == ORIENTATION_UNKNOWN) return;
int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_0:
android.util.Log.i(TAG, "changed ROTATION_0 - " + orientation);
break;
case Surface.ROTATION_90:
android.util.Log.i(TAG, "changed ROTATION_90 - " + orientation);
break;
case Surface.ROTATION_180:
android.util.Log.i(TAG, "changed ROTATION_180 - " + orientation);
break;
case Surface.ROTATION_270:
android.util.Log.i(TAG, "changed ROTATION_270 - " + orientation);
break;
}
if ((rotation != mLastRotation) && (rotation & 0x1) == (mLastRotation & 0x1))
{
android.util.Log.i(TAG, "unhandled orientation changed >>> " + rotation);
}
mLastRotation = rotation;
}
};
if (mOrientationEventListener.canDetectOrientation()){
mOrientationEventListener.enable();
}
OrientationEventListener
不是适用于180°方向变化的正确工具,因为它会在实时中不断触发,甚至在getRotation()
改变之前就会触发!DisplayListener
做得更好,因为它只在getRotation()
改变时才会触发。 - 0101100101您仍然需要使用显示监听器类:Google推荐用它来处理从未锁定方向的180度设备旋转。您不能简单地将所有对onDisplayChanged的回调视为180度旋转。来自Google的更完整的实现展示了如何在onDisplayChanged回调期间从Display manager收集Display旋转,正如superuser所提到的。
/** DisplayManager to listen to display changes */
private val displayManager: DisplayManager by lazy {
applicationContext.getSystemService(DISPLAY_SERVICE) as DisplayManager
}
/** Keeps track of display rotations */
private var displayRotation = 0
...
override fun onAttachedToWindow() {
super.onAttachedToWindow()
displayManager.registerDisplayListener(displayListener, mainLooperHandler)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
displayManager.unregisterDisplayListener(displayListener)
}
private val displayListener = object : DisplayManager.DisplayListener {
override fun onDisplayAdded(displayId: Int) {}
override fun onDisplayRemoved(displayId: Int) {}
override fun onDisplayChanged(displayId: Int) {
val difference = displayManager.getDisplay(displayId).rotation - displayRotation
displayRotation = displayManager.getDisplay(displayId).rotation
if (difference == 2 || difference == -2) {
createCaptureSession()
}
}
}