ImageView onTouch不会上下移动,只能围绕圆圈移动

时间:2016-12-16 12:40:45

标签: java android

我正在开发一个操纵杆按钮。在围绕圆圈移动时一切都很好,但是当我想要向上或向下移动它时,它从右侧再次绕圈。所以,我想要两个选项(像真正的操纵杆一样向上或向下移动)。这是我的代码示例。谢谢你的帮助

public class JoystickView extends FrameLayout implements View.OnTouchListener {

    private Context context;
    private ImageView backgroundImageView;
    private ImageView buttonImageView;
    private RelativeLayout relativeLayout;
    private View rootView;
    float xx = 0;
    float yy = 0;



    public JoystickView(Context context) {
        super(context);
        this.context = context;
        setLayout(this);
        buttonImageView.setOnTouchListener(this);
        this.setClipChildren(false);

    }

    public void setLayout(ViewGroup view) {

        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        View v = inflateControlerLayout();
        view.addView(v, layoutParams);
    }

    protected View inflateControlerLayout() {
        initSlider();
        rootView = relativeLayout;
        return rootView;

    }


    public void initSlider() {

        if (relativeLayout == null) {
            relativeLayout = new RelativeLayout(context);
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
            relativeLayout.setLayoutParams(layoutParams);
            relativeLayout.setClipChildren(false);
        }

        if (backgroundImageView == null) {
            backgroundImageView = new ImageView(context);

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
            backgroundImageView.setLayoutParams(layoutParams);

            // load image
            try {
                // get input stream
                InputStream ims = getContext().getAssets().open("joystick_background.png");
                // load image as Drawable
                Drawable d = Drawable.createFromStream(ims, null);
                // set image to ImageView
                backgroundImageView.setImageDrawable(d);
            } catch (IOException ex) {
                return;
            }
        }

        if (buttonImageView == null) {
            buttonImageView = new ImageView(context);

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, Gravity.CENTER);

            buttonImageView.setLayoutParams(layoutParams);


            // load image
            try {
                // get input stream
                InputStream ims2 = getContext().getAssets().open("jostick_button.png");
                // load image as Drawable
                Drawable d2 = Drawable.createFromStream(ims2, null);
                // set image to ImageView
                buttonImageView.setImageDrawable(d2);
                buttonImageView.bringToFront();
            } catch (IOException ex) {
                return;
            }
        }

        if (relativeLayout != null) {
            relativeLayout.addView(backgroundImageView);
            relativeLayout.addView(buttonImageView);
        }
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {


        switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:

                break;

            case MotionEvent.ACTION_UP:
                view.setX(xx);
                view.setY(yy);
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                break;

            case MotionEvent.ACTION_POINTER_UP:
                break;

            case MotionEvent.ACTION_MOVE:


                float cx = view.getWidth() / 2.f;
                float cy = view.getHeight() / 2.f;
                float x = motionEvent.getRawX();
                float y = motionEvent.getRawY();
                float w = buttonImageView.getWidth();
                float h = buttonImageView.getHeight();

                double r = Math.min(cx, cy) / 2.;
                double dx = x - cx;
                double dy = y - cy;
                double hypot = Math.hypot(dx, dy);
                double cos = dx / hypot;
                double sin = dy / hypot;
                double rdx = hypot < 1. ? 0. : r * cos;
                double rdy = hypot < 1. ? 0. : r * sin;

                buttonImageView.setTranslationX((float) (cx + rdx - w / 2.));
                buttonImageView.setTranslationY((float) (cy + rdy - h / 2.));

                break;
        }
        return true;

    }
}

2 个答案:

答案 0 :(得分:1)

这些线将坐标约束为圆(椭圆)路径或中心:

            double rdx = hypot < 1. ? 0. : r * cos;
            double rdy = hypot < 1. ? 0. : r * sin;

如果hypot小于1(即1个像素),您必须处于死亡中心。

我将其更改为仅约束圆圈内的坐标:

            double rcos = r * cos;
            double rsin = r * sin;
            double rdx = Math.abs(dx) < Math.abs(rcos) ? dx : rcos;
            double rdy = Math.abs(dy) < Math.abs(rsin)  ? dy : rsin;

我认为这可能就是你想要的。

答案 1 :(得分:0)

如果有人正在寻找,我找到了一个有效的解决方案

私人Point计算(float x,float y){

    float cx = buttonImageView.getWidth() / 2.f;
    float cy = buttonImageView.getHeight() / 2.f;

    double r = cx / 2.; // vrednost radius
    double dx = x;
    double dy = y;
    double hypot = Math.hypot(dx, dy); // izracun hipotenuze
    double cos = dx / hypot; // cos
    double sin = dy / hypot; // sin

    double rcos = r * cos;
    double rsin = r * sin;

    double rdx = Math.abs(dx) < Math.abs(rcos) ? dx : rcos; // if,else
    double rdy = Math.abs(dy) < Math.abs(rsin)  ? dy : rsin;

    return new Point((int)rdx, (int)rdy);

}

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {


    final float x = motionEvent.getRawX(); // x točko
    final float y = motionEvent.getRawY(); // y točka

    //Log.d("VALUES", "RAW X:" + motionEvent.getRawX() + ", RAW Y:" + motionEvent.getRawY() +  ", X:" + motionEvent.getX() + ", CX:" + cx + ", CY:" + cy + ", dx:" + dx + ", dy:" + dy + ", Hypo:" + hypot + ", cos:" + cos + ", sin" + sin);


    switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:

            xDelta = view.getX() - x;
            yDelta = view.getY() - y;

            break;

        case MotionEvent.ACTION_UP:

            doBounceAnimation(buttonImageView);
            doVibration();

            view.setX(xx);
            view.setY(yy);
            break;

        case MotionEvent.ACTION_POINTER_DOWN:
            break;

        case MotionEvent.ACTION_POINTER_UP:
            break;

        case MotionEvent.ACTION_MOVE:

            final float transX = (float) x;
            final float transY = (float) y;

            thread = new Thread() {
                @Override
                public void run() {

                    Point newPoint = calculate(transX+ xDelta,transY + yDelta);
                    buttonImageView.setX(newPoint.x);
                    buttonImageView.setY(newPoint.y);
                }
            };
            thread.start();




            Log.d(TRANSLATIONX,"X:" + transX + ", Y:" + transY);

            break;

    }
    return true;

}

享受编码!