android自定义View圆圈拖动
作者:呵呵HL 发布时间:2023-09-14 01:02:55
标签:android,拖动
本文实例为大家分享了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代表自己处理事件
}
}
来源:https://blog.csdn.net/hahawxian/article/details/115861512
0
投稿
猜你喜欢
- 前言多线程是我们开发过程中经常遇到的,也是必不可少需要掌握的。当我们知道需要进行多线程开发时首先需要知道的自然是如何实现多线程,也就是我们应
- 1.创建线程 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立
- 本文主要介绍了WPF中常用的鼠标事件、键盘事件以及注意事项,同时使用一个案例讲解了拓展事件。除此之外,本文还讲述如何用行为(Behavior
- 1.编写源代码编写源文件:CardLayoutDemo.java并保存,例如:I:\myApp\CardLayoutDemo.java。程序
- 详解Android Webview加载网页时发送HTTP头信息当你点击一个超链接进行跳转时,WebView会自动将当前地址作为Referer
- 用Dockerfile 构建一个java的编译环境,这里整理下实现步骤:1、包括以下软件包ubuntujdkmavensvn2、jdk、ma
- 本文实例讲述了Java实现的上传并压缩图片功能。分享给大家供大家参考,具体如下:先看效果:原图:1.33M处理后:27.4kb关键代码:pa
- 一、序言Java多线程编程线程池被广泛使用,甚至成为了标配。线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线
- 问题最近 Cordova 项目里有一个需求,这里需要从 assets 目录中读取文件,加载配置信息,并且代码中要用到。因为看到 gradle
- 我们知道二维数组,是在一维数组的基础上进行了维度的增加。那么在实际使用的过程中,有时候我们所需要的二维数组,它们其中的维度是不同的,这就需要
- 最近几年玩得最疯狂的应该是发红包了,尤其是过年的时候特别受欢迎,下面写了红包的随机算法,其实挺简单的,仅是提供一种思路,希望可以给大家一些启
- 需要修改Main方法第一行代码的路径为你的books.xml文件绝对路径或相对路径。代码演示了XPath各种语法的使用情况books.xml
- MyBatis简介MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参
- 有一天,你写了好多好多带“形参”的构造函数(就是“方法”,同义),而且需要向这些构造函数里传递同样的“实参”,然后你就憨憨地一个一个函数的调
- 本文实例讲述了C#使用默认浏览器打开网页的方法。分享给大家供大家参考。具体实现方法如下:public static bool OpenBro
- public static string Replace(string source, string match, string repla
- java 使用异常的好处总结一、分析Java异常处理机制确实比较慢,这个“比较慢”是相对于诸如String、Integer等对象来说,单单从
- JdbcTemplate概述它是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装。spring框架为我们提供了
- 1、数组数组的引用传递public class TestDemo1{public static void main(String args[
- 一、前言本博文标题和内容参考:基于原生JS实现H5转盘游戏博主将改编成Unity版本。二、效果图三、案例制作1.界面搭建使用了9个图片作为奖