Android ImageView从X度旋转到Y度跳跃问题

时间:2016-10-29 20:36:52

标签: android rotation slider ontouchlistener

我正在尝试在我的Android应用中实现旋转旋钮。目标是用户可以旋转旋钮来选择值以继续进行。

我实施了2张图片。一个是保持固定的旋钮圆,另一个是实际旋转的旋钮销。两个图像都很好地覆盖,只需要旋钮通过ImageView.rotation(degree)旋转。这是下面的图片。它的一张图像显示了2张图像。在实现中,我有圆形和图钉的单独图像视图。

Knob Circle and Pin

此处显示的引脚位置是静止位置(在photoshop中设计,旋转= 0)。但是,销只能从圆的一端旋转到另一端。

以下是代码实现,然后是实际问题:

XML中的

    <ImageView
        android:layout_width="410dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="-15dp"
        app:srcCompat="@drawable/ic_knob"
        android:adjustViewBounds="true"
        android:layout_gravity="center_horizontal|center_vertical"/>

    <ImageView
        android:layout_width="400dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="-15dp"
        android:adjustViewBounds="true"
        app:srcCompat="@drawable/ic_knob_pin"
        android:rotation="-150"
        android:id="@+id/game_activity_investment_knob_pin"
        android:layout_gravity="center_horizontal|center_vertical"/>

在Java中:

    ...
    investmentKnobPin = (ImageView) findViewById(R.id.game_activity_investment_knob_pin);
    investmentKnobPin.setOnTouchListener(new KnobTouchListener());
    ...

    private class KnobTouchListener implements View.OnTouchListener {

        private double mStartAngle = 0;
        private double mEndAngle = 0;
        private double mStartPosition;

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            final float xc = investmentKnobPin.getWidth() / 2;
            final float yc = investmentKnobPin.getHeight() / 2;

            final float x = event.getX();
            final float y = event.getY();

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:
                    mStartAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
                    mStartPosition = investmentKnobPin.getRotation();
                    break;

                case MotionEvent.ACTION_MOVE:
                    if (mEndAngle != 0) mStartAngle = mEndAngle;
                    mEndAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
                    double delta = mEndAngle - mStartAngle;
                    double finalPosition = mStartPosition + delta;
                    if(finalPosition <= 150 && finalPosition >= -150) 
                    {
                        animate(mStartPosition, finalPosition, 0);
                        mStartPosition = finalPosition;
                    }
                    break;

                case MotionEvent.ACTION_UP:
                    mStartAngle = mEndAngle = 0;
                    break;
            }
            return true;
        }

        private void animate(double fromDegrees, double toDegrees, long durationMillis) {
            final RotateAnimation rotate = new RotateAnimation(
                (float) fromDegrees, 
                (float) toDegrees, 
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
            rotate.setDuration(durationMillis);
            rotate.setFillEnabled(true);
            rotate.setFillAfter(true);
            investmentKnobPin.startAnimation(rotate);
        }
    }

问题: 如果我将XML中的初始旋转设置为0,则效果很好。它从中间位置开始,然后到达任何一个结尾。但是,我的要求是从右端(即-150度位置)开始直到另一端(即150度位置)。当我在XML中将初始旋转设置为-150时,引脚现在在触摸开始时跳到另一个点X,然后从不同的点X旋转到另一个不同的点Y,其中Y - X = 300度。不知道如何解决这个问题。我该如何实现呢?

在记录了从一个象限滑动到另一个象限的位置后,我注意到了一个巨大的度数跳跃。我该如何处理这个象限?

此外,我必须将MAX值分配给-150度点的位置,并且应该在150度点处减小到MIN值。由于象限问题导致程度变化不一致,我也无法弄清楚如何做到这一点。

需要帮助。我现在被困了10个小时。

1 个答案:

答案 0 :(得分:0)

YAY !!我解决了我必须编写自己的角度计算方法然后才能很好地工作。这是最终的代码。它可能对其他人有用:

Pane

玩得开心!