自定义拖动条android,自定义可拖动进度条

这篇博客介绍了一个自定义的Android View——ClockView,它绘制了一个圆形时钟,并实现了触摸滑动来改变秒针位置的功能。博客详细展示了如何初始化画笔、计算角度、更新UI以及处理触摸事件。此外,还涉及到视图的测量、绘制和触摸监听等Android UI开发关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

packagecom.example.myview;

importjava.text.DecimalFormat;

importandroid.content.Context;

importandroid.graphics.Canvas;

importandroid.graphics.Color;

importandroid.graphics.Paint;

importandroid.os.Handler;

importandroid.os.Message;

importandroid.util.AttributeSet;

importandroid.util.Log;

importandroid.view.MotionEvent;

importandroid.view.View;

public classClockView extendsView {

//用于发送消息修改UIprivateHandler handler;

privatePaint circlePaint, dialPaint, numberPaint;

//View的宽高private floatmWidth;

private floatmHeight;

//圆的半径private floatcircleRadius;

//圆的X,Y坐标private floatcircleX;

private floatcircleY;

//小针doublesecond= 87.50;

//private int minute;//小时private doublehour;

private floatsecondX;

private floatsecondY;

private booleanisFirst= true;

//内圆的X,Y坐标private floatcircleInX;

private floatcircleInY;

//被点击点x的坐标到圆心x轴的坐标private floatx;

//被点击点y坐标到圆心y轴的坐标private floaty;

publicClockView(Context context, AttributeSet attrs) {

super(context, attrs);

initPaint();

}

private voidinitPaint() {

Log.i("xyz","initPaint....................");

//TODO Auto-generated method stub//刻盘圆,小时刻度,时针和分针的画笔circlePaint= newPaint(Paint.ANTI_ALIAS_FLAG);

circlePaint.setColor(Color.BLACK);

circlePaint.setStyle(Paint.Style.STROKE);

circlePaint.setStrokeWidth(10);

//分钟钟刻度的画笔dialPaint= newPaint(Paint.ANTI_ALIAS_FLAG);

dialPaint.setColor(Color.BLACK);

dialPaint.setStrokeWidth(5);

//数字的画笔numberPaint= newPaint(Paint.ANTI_ALIAS_FLAG);

numberPaint.setColor(Color.BLACK);

numberPaint.setStrokeWidth(5);

numberPaint.setTextSize(30);

}

@Overrideprotected voidonMeasure(intwidthMeasureSpec, intheightMeasureSpec) {

//TODO Auto-generated method stubLog.i("xyz","onMeasure.......................");

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//getMesureWidth()获取到是这个View原始的大小也就是View在xml中确定的大小//通过getWidth()获得到的是View最后显示出来的大小//这两个方法最后得到的大小可能一样也可能不一样mWidth= getMeasuredWidth();

mHeight= getMeasuredHeight();

//判断拿到的原始View的大小,使用小的作为半径的参考,这样才不会出现圆不见了一部分if(mWidth< mHeight) {

//圆的半径为view的宽度的一半再减9,防止贴边circleRadius= mWidth/ 2- 9;

circleX= mWidth/ 2;

circleY= mHeight/ 2;

circleInX= circleX- 20;

circleInY= circleY- 20;

} else{

circleRadius= mHeight/ 2- 9;

circleX= mWidth/ 2;

circleY= mHeight/ 2;

circleInX= circleX- 20;

circleInY= circleY- 20;

}

}

@Overrideprotected voidonDraw(Canvas canvas) {

super.onDraw(canvas);

//画出圆的圆心,也就是外圆的圆心drawCirclePoint(canvas);

//画出外层的圆drawCircle(canvas);

//画出第二层的圆drawLittleCircle(canvas);

//画刻度,在这里了,没有调用该方法,你可以去掉看看效果//drawDial(canvas);//初始化环上小圆点drawPointer(canvas);

//画环上小圆点drawInPointer(canvas);

}

private voiddrawInPointer(Canvas canvas) {

circlePaint.setColor(Color.BLUE);

canvas.drawCircle((float) (secondX/ 0.85), (float) (secondY/ 0.85), (float) 5, circlePaint);

circlePaint.setColor(Color.BLACK);

}

@Overridepublic booleanonTouchEvent(MotionEvent event) {

if(event.getAction() == MotionEvent.ACTION_DOWN) {

x= (event.getX() - circleX);

y= (event.getY() - circleY);

changeView(x, y);

}

if(event.getAction() == MotionEvent.ACTION_MOVE) {

x= (event.getX() - circleX);

y= (event.getY() - circleY);

changeView(x, y);

}

if(event.getAction() == MotionEvent.ACTION_UP) {

x= (event.getX() - circleX);

y= (event.getY() - circleY);

changeView(x, y);

}

return true;

}

//当private voidchangeView(floatx, floaty) {

floatr;

r = (float) Math.sqrt(x * x + y * y);

//改变圆环上圆的位置,不懂得同学可以画一个图算算secondX= x / r * circleRadius* 0.8f;

secondY= y / r * circleRadius* 0.8f;

changeViewFirst(x + circleX, y + circleY);

invalidate();

}

private floatm_angle;

private voidchangeViewFirst(floatx, floaty) {

//坐标在第一象限if(x > circleX&& y < circleY) {

floatangle = (float) (Math.atan2(x - circleX, circleY- y) / 3.14* 180);

second= angle / 360* 20.5+ 87.50;

Log.i("xyz", "1:"+ second);

upTextView();

invalidate();

}

//坐标在第二象限if(x > circleX&& y > circleY) {

floatangle = (float) (90.0+ Math.atan2(y - circleY, x - circleX) / 3.14* 180);

second= angle / 360* 20.5+ 87.50;

Log.i("xyz", "2:"+ second);

upTextView();

invalidate();

}

//坐标在第三象限if(x < circleX&& y > circleY) {

floatangle = (float) (180.0+ Math.atan2(circleX- x, y - circleY) / 3.14* 180);

second= angle / 360* 20.5+ 87.50;

Log.i("xyz", "3:"+ second);

upTextView();

invalidate();

}

//坐标在第四象限if(x < circleX&& y < circleY) {

floatangle = (float) (270.0+ Math.atan2(circleY- y, circleX- x) / 3.14* 180);

second= angle / 360* 20.5+ 87.50;

Log.i("xyz", "4:"+ second);

upTextView();

invalidate();

}

}

//初始化移动小圆的坐标,其实这里可以做优化但是我没做懒得做了,只会跑一次private voiddrawPointer(Canvas canvas) {

canvas.translate(circleX, circleY);

if(isFirst) {

secondX= (float) Math.cos(Math.toRadians((second- (87.50)) * (360.00/ 20.50) + 270)) * circleRadius* 0.8f;

secondY= (float) Math.sin(Math.toRadians((second- (87.50)) * (360.00/ 20.50) + 270)) * circleRadius* 0.8f;

isFirst= false;

}

//canvas.drawLine(0,0,secondX,secondY,dialPaint);}

//画刻度,private voiddrawDial(Canvas canvas) {

//长刻度画笔Point startPoint = newPoint(circleX, circleY- circleRadius);

Point endPoint = newPoint(circleX, circleY- circleRadius+ 40);

//短刻度画笔Point startPoint2 = newPoint(circleX, circleY- circleRadius);

Point endPoint2 = newPoint(circleX, circleY- circleRadius+ 10);

//开始画刻度和数字,总共60个刻度,6个mHZ刻度,被10整除画一个mHZ刻度,被其余的为小刻度String clockNumber;

doublemHz = 87.50;

for(doublei = 0; i < 60; i++) {

if(i % 15== 0) {

if(i == 0) {

clockNumber = "87.50";

} else{

clockNumber = String.format("%.2f", (20.50* (i / 60) + 87.50));

}

//时针刻度canvas.drawLine(startPoint.getX(), startPoint.getY(), endPoint.getX(), endPoint.getY(), circlePaint);

//画数字,需在时针刻度末端加30使canvas.drawText(clockNumber, circleX- numberPaint.measureText(clockNumber) / 2, endPoint.getY() + 30, numberPaint);

} else{

//画小针刻度canvas.drawLine(startPoint2.getX(), startPoint2.getY(), endPoint2.getX(), endPoint2.getY(), circlePaint);

}

//画布旋转6度canvas.rotate(360/ 60, circleX, circleY);

}

}

//画出最大的圆private voiddrawCircle(Canvas canvas) {

canvas.drawCircle(circleX, circleY, circleRadius, circlePaint);

}

//画出内圆private voiddrawLittleCircle(Canvas canvas) {

canvas.drawCircle(circleX, circleY, circleRadius- 20, circlePaint);

}

//花圆点private voiddrawCirclePoint(Canvas canvas) {

circlePaint.setColor(Color.WHITE);

canvas.drawCircle(circleX, circleY, 5, circlePaint);

circlePaint.setColor(Color.BLACK);

}

//Acvitity跑起来的时候调用public voidstartClock(Handler handler) {

invalidate();

this.handler= handler;

upTextView();

}

//修改UI界面voidupTextView() {

DecimalFormat df = newDecimalFormat("######0.00");

Message message = Message.obtain();

message.obj= df.format(second);

handler.sendMessage(message);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值