android 上下控制方向盘_Android 自定义简易的方向盘操作控件

public classWheel extends View implements View.OnTouchListener{intxPosition;intyPosition;intcenterX;intcenterY;intmainRadius;intsecondRadius;

boolean isClicked;

OnMyWheelMoveListener myWheelMoveListener;publicWheel(Context context) {

super(context);

}publicWheel(Context context, @Nullable AttributeSet attrs) {

super(context, attrs);

}public Wheel(Context context, @Nullable AttributeSet attrs, intdefStyleAttr) {

super(context, attrs, defStyleAttr);

isClicked=false;

}

@Overrideprotected void onMeasure(int widthMeasureSpec, intheightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width =MeasureSpec.getMode(widthMeasureSpec)==MeasureSpec.UNSPECIFIED?100:MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getMode(heightMeasureSpec)==MeasureSpec.UNSPECIFIED?100:MeasureSpec.getSize(heightMeasureSpec);if(width>height){

width=height;

}else{

height=width;

}this.mainRadius=(getWidth()-100)/2;this.secondRadius=mainRadius/5*2;

setMeasuredDimension(width, height);this.centerX=getWidth()/2;this.centerY=getHeight()/2;this.xPosition=centerX;this.yPosition=centerY;

}

@Overrideprotected voidonDraw(Canvas canvas){

Bitmap bm;

Paint BackgroundPaint= newPaint(Paint.ANTI_ALIAS_FLAG);

BackgroundPaint.setFilterBitmap(true);

BackgroundPaint.setDither(true);

Paint circlePaint=newPaint();

circlePaint.setColor(Color.parseColor("#52c1bd"));

circlePaint.setStyle(Paint.Style.FILL);if(!isClicked){

bm=((BitmapDrawable)getResources().getDrawable(R.mipmap.circle1)).getBitmap();

}else{

bm=((BitmapDrawable) getResources().getDrawable(R.mipmap.circle)).getBitmap();

}

Rect mSrcRect= new Rect(0, 0, bm.getWidth(), bm.getHeight());

Rect mDestRect= new Rect(30, 30,getWidth()-30, getHeight()-30);

canvas.drawBitmap(bm,mSrcRect,mDestRect,BackgroundPaint);

canvas.drawCircle(this.xPosition,this.yPosition,secondRadius,circlePaint);

}

@Overridepublic boolean onTouch(View v, MotionEvent event) {return false;

}

@Overridepublic boolean onTouchEvent(MotionEvent event){

isClicked=true;this.xPosition = (int) event.getX();this.yPosition = (int) event.getY();if(Math.sqrt((this.xPosition-this.centerX)*(this.xPosition-this.centerX)+(this.yPosition-this.centerY)*(this.yPosition-this.centerY))>mainRadius){double Yrate=(this.yPosition-this.centerY)/Math.sqrt((this.xPosition-this.centerX)*(this.xPosition-this.centerX)+(this.yPosition-this.centerY)*(this.yPosition-this.centerY));double Xrate=(this.xPosition-this.centerX)/Math.sqrt((this.xPosition-this.centerX)*(this.xPosition-this.centerX)+(this.yPosition-this.centerY)*(this.yPosition-this.centerY));this.yPosition=(int)(mainRadius*Yrate)+this.centerY;this.xPosition=(int)(mainRadius*Xrate)+this.centerX;

}if(this.myWheelMoveListener!=null){this.myWheelMoveListener.onValueChanged(this.xPosition,this.yPosition);

}

invalidate();if(event.getAction()==1){

isClicked=false;this.yPosition=this.centerY;this.xPosition=this.centerX;if(this.myWheelMoveListener!=null){this.myWheelMoveListener.onValueChanged(this.xPosition,this.yPosition);

}

invalidate();

}return true;

}public voidsetOnMyWheelMoveListener(OnMyWheelMoveListener listener){this.myWheelMoveListener=listener;

}public static abstract interfaceOnMyWheelMoveListener {public abstract void onValueChanged(int xDistance, intyDistance);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在一些手机游戏中,玩家可以通过虚拟控制盘来控制游戏角色的行动。 无人机和玩具操App中也有这一类控制盘的应用。用自定义View的方式来实现类似手柄的件。相关代码请见 github.com/RustFisher/…JoystickView特性目前JoystickView特性如下2种风格固定控制盘;浮动跟随模式;控制盘会移动到手指第一次点击的地方可以在背景上添加“箭头”,即添加效果图片自定义的“触摸球”图片和背景图片手指移出了控制盘范围,仍然能够保持追随能获取到移动位置的百分比参数实现思路用自定义View的方式实现这个控制盘。创建TouchView。控制盘的基本要求是跟随手指做出反应。为了获取到手指触屏的坐标,会用到View的onTouchEvent方法。件中的“触摸球”和背景由图片得来。在自定义view中先获取相应的bitmap,缩放成指定的尺寸。onTouchEvent中获取到相应的坐标,计算出图片应该出现的位置;onDraw中根据坐标进行绘制。 计算出手指位置与控制盘中心的距离等信息,通过listener传递出去。代码示例样式设定有固定和浮动这两种风格,未来可能还会添加public enum PadStyle {     FLOATING /* 随用户手指重新定位 */,     FIXED    /* 固定位置 */ }控制盘配置我们可以不直接操作TouchView,创建TouchViewModel存放相关的配置。    private int bgResId;           // 背景图片资源ID     private int touchBmpResId;     // 触摸图资源ID - 例如一个圆球     private int directionPicResId; // 指示当前触摸点与圆心相对方向的图片ID     private float mWholeViewWid;    // 整个View的宽     private float mWholeViewHeight; // 整个View的高     private float mWholePadWid;    // 盘的宽度,包括箭头;并不是View的总宽度     private float mWholePadHeight; // 盘的高度,包括箭头;并不是View的总宽度     private int mRoundBgRadius;    // 背景圆的半径 背景圆位置可以变化     private int mTouchBallRadius = 100; // 触摸球的半径     private int mRoundBgPadding;   // 背景圆到Pad边界的px  一般是留给方向箭头的位置     private boolean showDirectionPic = false;    // 是否显示指示图片     private PadStyle mPadStyle = PadStyle.FIXED; // 默认为固定位置的     private PadLocationType mPadLocationType = PadLocationType.LEFT_BOT;     // .........控制盘管理器控制盘的配置项比较多,抽象出一个DefaultController来管理控制盘。这个控制器不是必要的。 管理器需要控制盘所在的父View,这里用的是RelativeLayout。创建一个“左控制盘”。将各个尺寸配置传入。最后添加到containerView中。    private void createLeftControlTouchView() {         TouchViewModel model = new TouchViewModel(                 R.drawable.ui_pic_joystick_left_pad,                 R.drawable.ui_pic_joystick_control_ball);         model.setWholeViewSize(ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_whole_field_wid),                 ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_whole_field_height));         model.setPadSize(ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_pad_size),                 ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_pad_size));         int roundBgRadius = ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_round_bg_radius);         model.setContentSize(roundBgRadius, (int) (roundBgRadius / 3.5));         model.setStyle(padStyle, PadLocationType.LEFT_BOT);         model.setRoundBgPadding(ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_circle_bg_padding));         leftControlTouchView = new TouchView(ctx);         leftControlTouchView.init(model);         // View的总大小         RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(                 ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_whole_field_wid),                 ctx.getResources().getDimensionPixelSize(R.dimen.ui_joystick_whole_field_height)         );         params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);         params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);         leftControlTouchView.setLayoutParams(params);     }     // ............     createLeftControlTouchView();     containerView.addView(leftControlTouchView);管理器初始化时需要一个ViewGroup来承载控制盘。    public DefaultController(Context context, RelativeLayout containerView, PadStyle padStyle) {         this.ctx = context;         this.containerView = containerView;         this.padStyle = padStyle;     }Fragment中使用初始化管理器初始化管理器,创建控制盘    mDefaultController =             new DefaultController(getContext(),                     (RelativeLayout) root.findViewById(R.id.joystick_container));     mDefaultController.createViews();     mDefaultController.showViews(false);设置监听器,获取用户的操作信息通过控制器来设置监听器        mDefaultController.setLeftTouchViewListener(new JoystickTouchViewListener() {             @Override             public void onTouch(float horizontalPercent, float verticalPercent) {                 Log.d(TAG, "onTouch left: "   horizontalPercent   ", "   verticalPercent);             }             @Override             public void onReset() {                 Log.d(TAG, "onReset: left");             }             @Override             public void onActionDown() {                 Log.d(TAG, "onActionDown: left");             }             @Override             public void onActionUp() {                 Log.d(TAG, "onActionUp: left");             }         });至此,我们实现了一个简单的控制件。在一些控制类应用中可以使用这个件。若想要做出更优美,更吸引人的件,需要我们有好的审美水平。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值