Android Studio中实现摇杆

今天和大家分享一下Android Studio实现摇杆,原理很简单,代码中有对应的注释。

实现效果图

在这里插入图片描述
在这里插入图片描述

实现代码

package com.example.fragmentcar1.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * 摇杆视图
 */
public class RemoteView extends View {
    Paint backPaint = new Paint();//背景画笔
    Paint bubblePaint = new Paint();//气泡画笔
    Paint rectfPaint = new Paint();
    /**
     * 气泡的位置
     */
    float bubbleX = 300, bubbleY = 300;

    /**
     * 背景圆的位置
     */
    float backX = 300, backY = 300;
    /**
     * 气泡和背景的半径
     */
    int radiusBack = 200, radiusBubble = 100;

    RectF mRectF = new RectF(backX-radiusBack,backY-radiusBack,backX+radiusBack,backY+radiusBack);


    Context mContext;

    /**
     * STOP  停止
     * RETURN 后退
     * LEFT 左转
     * RIGHT 右转
     * GO 前进
     * 默认为停止
     */
    String orientation="STOP";

    public RemoteView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;

    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        initPaint();
        canvas.drawCircle(backX, backY, radiusBack, backPaint);

        if (orientation=="GO") {
            canvas.drawArc(mRectF, -45, -90, true, rectfPaint);
        }else if (orientation=="RETURN"){
            canvas.drawArc(mRectF, 45, 90, true, rectfPaint);
        }else if (orientation=="LEFT"){
            canvas.drawArc(mRectF, 135, 90, true, rectfPaint);
        }else if (orientation=="RIGHT"){
            canvas.drawArc(mRectF, -45, 90, true, rectfPaint);

        }else if (orientation=="STOP"){
            rectfPaint.setAlpha(0);
            canvas.drawArc(mRectF, -90, 360, true, rectfPaint);
        }


        canvas.drawCircle(bubbleX, bubbleY, radiusBubble, bubblePaint);


    }

    private void initPaint() {
        backPaint.setAntiAlias(true);
        backPaint.setColor(Color.parseColor("#60ffffff"));

        bubblePaint.setAntiAlias(true);
        bubblePaint.setColor(Color.parseColor("#90ffffff"));

        rectfPaint.setAntiAlias(true);
        rectfPaint.setColor(Color.parseColor("#ffffff"));
        rectfPaint.setAlpha(144);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                float x = (int) event.getX();
                float y = (int) event.getY();

                if (getDistance(x, y, backX, backY) < radiusBack) {
                    bubbleX = x;
                    bubbleY = y;
                } else if (getDistance(x, y, backX, backY) >= radiusBack) {
                    float xAndy[];
                    xAndy = getXY(x, y, backX, backY, getDistance(x, y, backX, backY));
                    bubbleX = xAndy[0];
                    bubbleY = xAndy[1];
                    getOrientation(x,y);


                }
                break;
            case MotionEvent.ACTION_UP:
                bubbleX = backX;
                bubbleY = backY;
                orientation="STOP";
                break;
        }
        invalidate();

        return true;
    }

    /**
     * 得到手指触控点与圆点中心的距离
     *
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return
     */
    private float getDistance(float x1, float y1, float x2, float y2) {
        float dis;
        dis = (float) Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        return dis;
    }

    /**
     * 当手指触控点在大圆外面时
     * 需要重新得到气泡的位置
     *
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @param dis
     * @return
     */
    private float[] getXY(float x1, float y1, float x2, float y2, float dis) {
        float[] xAndy = new float[2];
        float scaleDis;
        float xDis;
        float yDis;


        /**
         * 表示在第一象限之内
         */
        if (x1 > x2 && y1 < y2) {
            scaleDis = radiusBack / dis;
            xDis = Math.abs(x1 - x2);
            yDis = Math.abs(y1 - y2);
            xAndy[0] = x2 + xDis * scaleDis;
            xAndy[1] = y2 - yDis * scaleDis;

        }
        /**
         * 表示在第二象限之内
         */
        else if (x1 < x2 && y1 < y2) {
            scaleDis = radiusBack / dis;
            xDis = Math.abs(x1 - x2);
            yDis = Math.abs(y1 - y2);
            xAndy[0] = x2 - xDis * scaleDis;
            xAndy[1] = y2 - yDis * scaleDis;
        }
        /**
         *表示在第三象限之内
         */
        else if (x1 < x2 && y1 > y2) {
            scaleDis = radiusBack / dis;
            xDis = Math.abs(x1 - x2);
            yDis = Math.abs(y1 - y2);
            xAndy[0] = x2 - xDis * scaleDis;
            xAndy[1] = y2 + yDis * scaleDis;
        }

        /**
         * 表示在第四象限之内
         */
        else if (x1 > x2 && y1 > y2) {
            scaleDis = radiusBack / dis;
            xDis = Math.abs(x1 - x2);
            yDis = Math.abs(y1 - y2);
            xAndy[0] = x2 + xDis * scaleDis;
            xAndy[1] = y2 + yDis * scaleDis;
        }

        /**
         * 角度为零度
         */
        else if (x1 > x2 && y1 == y2) {
            xAndy[0] = x2 + radiusBack;
            xAndy[1] = y2;
        }

        /**
         * 角度为90度
         */
        else if (x1 == x2 && y1 < y2) {
            xAndy[0] = x2;
            xAndy[1] = y2 - radiusBack;
        }

        /**
         * 角度为180度
         */
        else if (x1 < x2 && y1 == y2) {
            xAndy[0] = x2 - radiusBack;
            xAndy[1] = y2;
        }

        /**
         * 表示为270度
         */
        else if (x1 == x2 && y1 > y2) {
            xAndy[0] = x2;
            xAndy[1] = y2 + radiusBack;
        }
        return xAndy;
    }
    /**
     * 更具摇杆操作的方向来控制小车的运动方向
     */
    private void getOrientation(float x,float y){
        if (y<backY&&(x<backX+backX*0.707&&x>backY-backY*0.707)){
             orientation = "GO";
        }else if (x>backX&&(y<backY+backY*0.707&&y>backY-backY*0.707)){
            orientation="RIGHT";
        }else if (y>backY&&(x<backX+backX*0.707&&x>backY-backY*0.707)){
            orientation="RETURN";
        }else if (x<backX&&(y<backY+backY*0.707&&y>backY-backY*0.707)){
            orientation="LEFT";
        }else {
            orientation="STOP";
        }

    }


}

  • 7
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Android Studio是一款流行的开发工具,可以帮助开发者搭建出高质量的Android应用。在Android Studio摇杆是一种常见的UI元素,可以方便用户进行移动和交互。 摇杆通常包括一个圆形的心点和周围的轨迹。当用户按住摇杆并向左或向右移动时,摇杆心点会随着手势的移动而移动,同时生成对应的事件并传递给应用程序。程序可以根据事件的值来响应摇杆位置的变化,并执行相应的行为。 在Android Studio,开发者可以使用预先定义的图像资源或自定义图像来创建摇杆。此外,还可以使用xml属性来改变摇杆的属性,例如颜色、大小等等。 总之,Android Studio摇杆是一种非常实用和有用的UI元素,可以帮助开发者轻松创建出具有交互性和动态性的应用程序。 ### 回答2: Android Studio摇杆是指一个可以模拟手动控制器的控件,用于模拟移动设备或游戏摇杆控制器,实现用户交互与游戏的联动。摇杆控件通常由两个半球组成,心为两个半球的接点,通过手指在半球上的滑动来模拟方向键的控制。 在Android Studio使用摇杆控件需要先引入相关的库,通常是通过Gradle依赖添加相关库文件实现。在使用摇杆控件时,需要在组件定义摇杆控件的形状、大小、位置等属性,并通过监听控制器的位置变化实现对其控制。 与其他控制器相比,摇杆控件灵活性比较高,在游戏开发广泛应用,例如射击游戏的方向控制、体育游戏的角度控制等。 相比其他的控件,摇杆控件对手指的精准交互较高,用户可以更加直观地感受到自己的操作效果。 综上所述,Android Studio摇杆控件可以实现模拟手动控制器的效果,广泛应用于游戏开发领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值