如何从不同角度旋转视图?

How to rotate a view from different angles?

我正在尝试将 ImageButton 旋转 180 度,使其与反向纵向匹配。当我以与其他方向更改相同的方式执行此操作时,结果是完美的,但动画不是。

 public void onOrientationChanged(int DeviceAngle) {
      float MyButtonCurrentAngle = MyButton.getRotation(); //Gets portrait rotation (0)
           if(DeviceAngle > 350 || DeviceAngle < 10) { //Portrait
                MyButton.animate().rotationBy(- MyButtonCurrentAngle).setDuration(100).start();
           } else if(DeviceAngle > 80 && DeviceAngle < 100) { //Reverse Landscape
                MyButton.animate().rotationBy(-90 - MyButtonCurrentAngle ).setDuration(100).start();
            } else if(DeviceAngle > 170 && DeviceAngle < 190) { //Reverse Portrait
                MyButton.animate().rotationBy(180 -  MyButtonCurrentAngle).setDuration(100).start();
           } else if(DeviceAngle > 260 && DeviceAngle < 280) { //Landscape
                MyButton.animate().rotationBy(90 - MyButtonCurrentAngle ).setDuration(100).start();
           }          

我认为会发生这种情况,因为浮动 MyButtonCurrentAngle 从 350 到 10(0 或 360,纵向方向)之间的 DeviceAngle 获取 MyButton 旋转角度值(0 或未旋转)并将其用作参考。

尽管我还在怀疑,但我还是放弃了之前的案例。浮动似乎与其他方向配合得很好,我认为问题在于反向纵向方向的动画。按钮不应旋转 180 度,而应旋转 90 度或 -90 度。这是因为您无法在不通过任一横向选项的情况下将设备从纵向旋转到反向纵向。 (不能直接旋转人像来反转人像)。

经过多次不成功的尝试,我得出的结论是,在旋转按钮并且检测到的方向是横向或反向横向后,我无法使用 MyButton 获取角度值。我考虑过创建另一个浮动来获取 Reverse Portrait MyButton 角度值,但是这个 activity 的方向设置为 Portrait,所以这没有意义。

因此,我需要得到MyButton用float旋转后的旋转角度,使用这个值作为循环条件,根据结果,在两个不同的动画中旋转90度或-90度。这是我对这个问题的最新处理方法:

    while (MyButtonCurrentAngle==90) { 
    if (DeviceAngle > 170 && DeviceAngle < 190) {
        MyButton.animate().rotationBy(90 - MyButtonCurrentAngle).setDuration(100).start();
    }
}
while (MyButtonCurrentAngle==270) { 
    if (DeviceAngle > 170 && DeviceAngle < 190) {
        MyButton.animate().rotationBy(-90 - MyButtonCurrentAngle).setDuration(100).start();
    }
}

基本上,这处理了从横向和反向横向到反向纵向的设备方向。这没有触发任何动画,所以 MyButtonCurrentAngle 浮动角度值从未改变或无法检测到?为什么 if 语句不能读取它?我不知道,我想知道我做错了什么。提前致谢。

如果您发现此代码是 运行(通过断点调试或 Logcat 语句),则尝试 运行 UI 线程上的动画.

YourActivity.runOnUiThread(new Runnable() {
    public void run() 
        MyButton.animate().rotationBy(90 - MyButtonCurrentAngle).setDuration(100).start();
    }
});

您可能还需要为此调用 start。

解决方案:

  OrientationEventListener OrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_UI) {
        static final int DELTA = 20;

        @Override 
        public void onOrientationChanged(int Angle) {
            float AngleDestination = ButtonDestination;
            if (angle > 90 - DELTA && angle < 90 + DELTA) {
                AngleDestination = -90;
            } else if (Angle > 180 - DELTA && Angle < 180 + DELTA) {
                AngleDestination = 180;
            } else if (Angle > 270 - DELTA && Angle < 270 + DELTA) {
                AngleDestination = 90;
            } else if (Angle > 360 - DELTA || Angle < DELTA) {
                AngleDestination = 0;
            } 
            if (AngleDestination != ButtonDestination) {
                ButtonDestination = AngleDestination;
                MyButton.animate().rotation(ButtonDestination).setDuration(100).start(); 
            } 
        } 
    }; 
    orientationEventListener.enable();
}