如何使用SensorEventListener检测设备方向?

时间:2015-10-07 04:09:57

标签: imagebutton screen-orientation android-sensors sensormanager rotateanimation

我想通过实现SensorEventListener来检测设备屏幕方向,因为默认情况下它的当前屏幕方向设置为纵向。我需要这样做,因为我的布局包括一些应该独立于其布局旋转的按钮,并且执行此操作的唯一方法(只要我知道)是通过覆盖onConfigurationChanged并向每个屏幕方向添加相应的动画。我不认为OrientationEventListener可以工作,因为设置方向固定为纵向。那么如何从传感器本身检索屏幕方向或角度旋转呢?

1 个答案:

答案 0 :(得分:3)

OrientationEventListener即使在固定方向下也能正常工作;见https://stackoverflow.com/a/8260007/1382108。它根据文档监控传感器。 假设您定义以下常量:

private static final int THRESHOLD = 40;
public static final int PORTRAIT = 0;
public static final int LANDSCAPE = 270;
public static final int REVERSE_PORTRAIT = 180;
public static final int REVERSE_LANDSCAPE = 90;
private int lastRotatedTo = 0;

这些数字对应于OrientationEventListener返回的内容,因此如果您有自然景观设备(平板电脑),则必须考虑到这一点,请参阅How to check device natural (default) orientation on Android (i.e. get landscape for e.g., Motorola Charm or Flipout)

 @Override
public void onOrientationChanged(int orientation) {
    int newRotateTo = lastRotatedTo;
    if(orientation >= 360 + PORTRAIT - THRESHOLD && orientation < 360 ||
            orientation >= 0 && orientation <= PORTRAIT + THRESHOLD)
        newRotateTo = 0;
    else if(orientation >= LANDSCAPE - THRESHOLD && orientation <= LANDSCAPE + THRESHOLD)
        newRotateTo = 90;
    else if(orientation >= REVERSE_PORTRAIT - THRESHOLD && orientation <= REVERSE_PORTRAIT + THRESHOLD)
        newRotateTo = 180;
    else if(orientation >= REVERSE_LANDSCAPE - THRESHOLD && orientation <= REVERSE_LANDSCAPE + THRESHOLD)
        newRotateTo = -90;
    if(newRotateTo != lastRotatedTo) {
        rotateButtons(lastRotatedTo, newRotateTo);
        lastRotatedTo = newRotateTo;
    }
}

rotateButtons函数类似于:

public void rotateButtons(int from, int to) {

    int buttons[] = {R.id.buttonA, R.id.buttonB};
    for(int i = 0; i < buttons.length; i++) {
        RotateAnimation rotateAnimation = new RotateAnimation(from, to, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setInterpolator(new LinearInterpolator());
        rotateAnimation.setDuration(200);
        rotateAnimation.setFillAfter(true);
        View v = findViewById(buttons[i]);
        if(v != null) {
            v.startAnimation(rotateAnimation);
        }
    }
}