本文实例为大家分享了android自定义View圆圈拖动的具体代码,供大家参考,具体内容如下
问题:
1 . 累加问题:“点击坐标”坐标在移动时必须改变位置,不然将导致累加过载
2. 圆形改变问题,每次刷新时圆必将改变位置
3. 图片平移:圆在移动时只要
public class MovingBlockView extends View { //画笔 Paint paint = new Paint(); Region circleRegion; Path circlePath; private boolean Move; /*圆心*/ private float x = 300; private float y = 300; /*点击坐标*/ private float ClickX = 0; private float ClickY = 0; /*圆心移动距离*/ private float moveX; private float moveY; /* * 圆形拖到问题: * 1 。累加问题:“点击坐标”坐标在移动时必须改变位置,不然将导致累加过载 * 2. 圆形改变问题,每次刷新时圆必将改变位置 * 3.图片平移:圆在移动时只要 * * */ public MovingBlockView(Context context) { this(context, null); } public MovingBlockView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public MovingBlockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); /*mPaint = new Paint(); mPaint.setColor(Color.RED);*/ paint.setColor(Color.RED); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); circlePath = new Path(); x = x + moveX; y = y + moveY; circlePath.addCircle(x, y, 300, Path.Direction.CW); Region region = new Region(0, 0, getMeasuredWidth(), getMeasuredHeight()); circleRegion = new Region(); circleRegion.setPath(circlePath, region); canvas.drawPath(circlePath, paint); canvas.drawLine(x + moveX, 0, x + moveX, getHeight(), paint); canvas.drawLine(0, y + moveY, getWidth(), y + moveY, paint); // canvas.drawCircle(); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN) { boolean cOntains= circleRegion.contains((int) event.getX(), (int) event.getY()); if (contains) { // Toast.makeText(getContext(), "点击了圆", Toast.LENGTH_LONG).show(); Move = true; ClickX = event.getX(); ClickY = event.getY(); Log.d(TAG, "ACTION_DOWN: " + ClickX); Log.d(TAG, "ACTION_DOWN: " + ClickY); } } else if (action == MotionEvent.ACTION_UP) { x = x + moveX; y = y + moveY; Move = false; Log.d(TAG, "ACTION_UP: "); } else if (action == MotionEvent.ACTION_MOVE) { if (Move) { Log.d(TAG, "ACTION_MOVE: "); moveX = event.getX() - ClickX; moveY = event.getY() - ClickY; ClickX = event.getX(); ClickY = event.getY(); Log.d(TAG, "ACTION_MOVE: " + moveX); Log.d(TAG, "ACTION_MOVE: " + moveY); invalidate(); } } return super.onTouchEvent(event); } }
小编再为大家分享一段之前收藏的代码:android自定义view圆形可移动
public class Mycircle2 extends View { private Paint paint; private int rawX; private int rawY; private int wid; private int he; int statusBarHeight1 = -1; //构造方法,一般会重写三个 //用于初始化一些数据,或者其他东西 public Mycircle2(Context context) { this(context,null); } public Mycircle2(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public Mycircle2(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //初始化画笔 //抗锯齿 paint = new Paint(Paint.ANTI_ALIAS_FLAG); //设置画笔 paint.setColor(Color.GREEN);//设置画笔颜色 paint.setStrokeWidth(3);//设置画笔粗细 //获取整个屏幕的高度和宽度 DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); wid = displayMetrics.widthPixels; he = displayMetrics.heightPixels; //获取status_bar_height资源的ID 获取状态栏的高度 int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { //根据资源ID获取响应的尺寸值 statusBarHeight1 = getResources().getDimensionPixelSize(resourceId); } } //重写绘制的方法 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(50,50,50,paint); /* paint.setColor(Color.LTGRAY); //实例化路径 Path path = new Path(); path.moveTo(80, 200);// 此点为多边形的起点 path.lineTo(120, 250); path.lineTo(80, 250); path.close(); // 使这些点构成封闭的多边形 canvas.drawPath(path, paint);*/ } //拖动事件 //拖动的实现原理: /** * 每个View在屏幕上都有个坐标,也就是上下左右边距,在屏幕上都有(x,y)坐标。如果坐标移动,那么View的位置也会移动 * ,这是比较好理解的。 * 我们手指在手机屏幕上滑动的时候,手指的坐标也是移动的。 * 我们只需要获得手指从按下到离开过程中的距离差,然后将距离差加到原来的坐标上就可以是实现控件的移动。 * 如果要实现拖动,那么在滑动的过程中,不断的获取距离差,不断的加到原来的坐标就可以了。 * 注意: * 这里的移动是相对于屏幕的,所以我们获取坐标应该是绝对坐标,而不是相对坐标 * event.getRawX() ---- 获取绝对X坐标 * event.getRawY() ---- 获取绝对Y坐标 * * event.getX()-------- 获取相对坐标x * event.getY()-------- 获取相对坐标Y * */ // onTouchEvent 处理触摸事件 //Touch事件:1.按下ACTION_DOWN,2.抬起ACTION_UP,3 滑动 ACTION_MOVE 4.取消ACTION_CANCEL //获取触摸点的坐标 //绝对坐标---相对于屏幕来说 //相对坐标---相对于自己 //event.getAction() 获取事件 @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: //获取开始的坐标 rawX = (int) event.getRawX(); rawY = (int) event.getRawY(); break; case MotionEvent.ACTION_MOVE: //获取移动时候的坐标 int yX = (int) event.getRawX(); int yY = (int) event.getRawY(); //减去手指按下时候的坐标 //得到移动的间距 int jX=yX-rawX; int jY=yY-rawY; //将间距,加到原来的坐标(上下左右) int l=getLeft()+jX; int r=getRight()+jX; int t=getTop()+jY; int b=getBottom()+jY; //判断 if(l<0){ l=0; r=getWidth(); } if(t<0){ t=0; b=getHeight(); } if(r>wid){ r=wid; l=wid-getHeight(); } //如果移动到最下边,就判断是否等于屏幕高度减去状态栏高度 if(b>he-statusBarHeight1){ //赋值 b=he-statusBarHeight1; t=b-getHeight(); } //重新赋值给布局 layout(l,t,r,b);//规定了View的位置 //将lastX,lastY重新赋值 rawX=yX; rawY=yY; break; case MotionEvent.ACTION_UP: break; } return true;//返回true代表自己处理事件 } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。