Android动画可以在触摸时移动圆圈中的图像按钮

时间:2014-08-01 04:05:10

标签: android android-animation

我有一个图像视图(例如:世界地图),其中我有很少的位置点。位置点是图像按钮,只有一个方形图像和一个写在正方形下方的文本。我有一个自定义的相对布局,处理触摸以圆形方式旋转地球仪。

现在,如何保持图像按钮的文本与x轴保持平行,换句话说,当我触摸和旋转地球时,平行于屏幕的宽度?触摸和旋转地球时,图像按钮会以一定角度旋转。

在触摸和旋转背景地球时,是否有人可以提供保持图像按钮文本始终与x轴平行所需的动画?我的指针是以小圆形方式(在不可见的圆形路径中)移动图像按钮,使文本始终与屏幕宽度平行。这种方法的一个小缺点是按钮将从其原始位置以圆形方式稍微移动。

任何人都可以帮助Android动画在图像视图顶部的小圆形路径上移动图像按钮吗?

我的布局如下 `

<com.mycompany.view.RotateRelativeLayout
        android:id="@+id/test_relative_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/test_bottom_bar"
        android:layout_marginTop="@dimen/test_margin_top"
        android:layout_centerInParent="true">

        <ImageView
            android:id="@+id/test_globe"
            android:layout_width="@dimen/test_layout_width"
            android:layout_height="@dimen/test_layout_height" />

        <FrameLayout
            android:id="@+id/test_frame_layout"
            android:layout_width="@dimen/test_layout_width"
            android:layout_height="@dimen/test_layout_height">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <ImageButton
                    android:id="@+id/test_button1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="@null"/>

                <ImageButton
                    android:id="@+id/test_button2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_below="@id/test_button1"
                    android:background="@null"/>
            </RelativeLayout>
        </FrameLayout>
    </com.mycompany.view.RotateRelativeLayout>

`

我用来触摸和旋转地球的自定义相对布局如下

`

public class RotateRelativeLayout extends RelativeLayout {
    private float mCenterX, mCenterY;
    private float direction = 0;
    private float sX, sY;
    private float startDirection = 0;

    public RotateRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    private double angleBetween2Lines(float centerX, float centerY, float x1,
                                      float y1, float x2, float y2) {
        double angle1 = Math.atan2(y1 - centerY, x1 - centerX);
        double angle2 = Math.atan2(y2 - centerY, x2 - centerX);
        return angle1 - angle2;
    }

    private void touchStart(float x, float y) {
        mCenterX = this.getWidth() / 2;
        mCenterY = this.getHeight() / 2;
        sX = x;
        sY = y;
    }

    private void touchMove(float x, float y) {
        // this calculates the angle the image rotate
        float angle = (float) angleBetween2Lines(mCenterX, mCenterY, sX, sY, x, y);
        direction = (float) Math.toDegrees(angle) * -1 + startDirection;
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();
        setRotation(direction);
        super.dispatchDraw(canvas);
        canvas.restore();
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // record the start position of finger
                touchStart(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                // update image angle
                touchMove(x, y);
                break;
            case MotionEvent.ACTION_UP:
                startDirection = direction;
                break;
        }

        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        onTouchEvent(event);
        return super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        onTouchEvent(event);
        return super.dispatchTouchEvent(event);
    }
}

`

因此,基本上我的相对布局应该响应触摸事件并为图像按钮设置动画。我试过这里,但这不起作用 `

final RotateRelativeLayout rotateRelativeLayout = (RotateRelativeLayout) view.findViewById(R.id.test_relative_layout);
        rotateRelativeLayout.setOnTouchListener(new View.OnTouchListener() {
            private float mCenterX = rotateRelativeLayout.getWidth() / 2.0f;
            private float mCenterY = rotateRelativeLayout.getHeight() / 2.0f;

            private void animate(View view, double fromDegrees, double toDegrees, long duration) {
                final RotateAnimation rotate = new RotateAnimation((float) fromDegrees, (float) toDegrees,
                        RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                        RotateAnimation.RELATIVE_TO_SELF, 0.5f);
                rotate.setDuration(duration);
                rotate.setFillEnabled(true);
                rotate.setFillAfter(true);
                rotate.setInterpolator(new LinearInterpolator());
                rotate.setRepeatCount(1);
                view.startAnimation(rotate);
            }

            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                float x = motionEvent.getX();
                float y = motionEvent.getY();
                final ImageButton imageButton = (ImageButton) view.findViewById(R.id.test_button1);

                double angle1 = 0, angle2 = 0;

                switch(motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        angle1 = Math.toDegrees(Math.atan2(y - mCenterY, x - mCenterX));
                        break;

                    case MotionEvent.ACTION_MOVE:
                        angle2 = Math.toDegrees(Math.atan2(y - mCenterY, x - mCenterX));
                        animate(imageButton, -angle1, -(angle2-angle1), 0);
                        break;

                    case MotionEvent.ACTION_UP:

                        break;
                }

                return true;
            }
        });

`

0 个答案:

没有答案