转载请标明出处:http://blog.csdn.net/u012724947/article/details/53237191
最近公司招聘打个广告:
公司属于外企福利待遇好,
每周英语课,
关键时单身妹子多[色][色]
详情 [点击全栈JavaScript工程师]
英文版 《Full Stack JavaScript Developer》
作为一名Android开发人员从码农 -> 程序员 -> 工程师进步的过程中必然少不了一些重要的过程, 好久没有自定义View了也是最近项目需要 ,这是Android版本的定义,如果需要查看IOS请点击《 IOS Swift自定义View – 圆形进度条,文字旋转》 ,欢迎大家提出宝贵意见,共同学习和进步,文章暂时没写全,以后补上,需要代码联系本人谢谢
实现的方法有很多种,万变不离其宗, 我们学习的是方法而不是死记硬背,或者拿来主义
//创建画笔
Paint paint = new Paint();
//设置红色
paint.setColor(Color.RED);
//设置画笔的锯齿效果。 true是去除, 画出的圆会更加光滑
paint.setAntiAlias(true);
//这是画圆形
canvas.drawCircle(100, 100, 100, paint);
// 设置矩形为灰色
paint.setColor(Color.GRAY);
//设置矩形填满
paint.setStyle(Paint.Style.FILL);
//绘制矩形
canvas.drawRect(60, 90, 160, 100, paint);// 长方形
//绘制文字
canvas.drawText("+", 10, 80, paint);
canvas.drawText("-", 10, 80, paint);
//绘制小球,和刚才画圆一样
canvas.drawCircle(10, 10, 10, paint);
角度是如何计算呢(这里我们需要区分在第几象限)
我们监听手势的x,y坐标 (与圆心构成三角形,长a,高b)
计算 所以 tan角度 = b / a (第三象限) 其它的也一样
圆上的点基本可以表示
最近Android Studio 出现问题展示把它卸载了 先上swift3.0 的代码 原理都一样应该大家也可以看懂
func LeftRoundAction(_ sender: UIPanGestureRecognizer){
if(CurrLeftProgress>=0 && CurrLeftProgress<=100){
let translation = sender.translation(in: self)
if(sender.state == UIGestureRecognizerState.possible){
}else if(sender.state == UIGestureRecognizerState.began){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.changed){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.ended){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
leftEX = translation.x + leftEX
leftEY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.cancelled){
}else if(sender.state == UIGestureRecognizerState.failed){
}else if(sender.state == UIGestureRecognizerState.recognized){
}
//两种情况 y > r or y < r 计算角度 和 新的坐标
var a:CGFloat=0;
var b:CGFloat=0;
if(leftY > centerY){
a = leftY - centerY
b = centerX - leftX
}else{
a = centerX - leftY
b = centerY - leftX
}
let tanA = a / b;
if(leftY > centerY){
leftY = centerY + radius * sin(atan(tanA)) - smallRoundR
let angle = CGFloat(M_PI_2 - M_PI_2 * 0.025) - atan(tanA)
if (abs(self.angleLeft - angle) < 0.3 || self.angleLeft == 0){
self.angleLeft = angle
}else{
return
}
}else{
leftY = centerY - radius * sin(atan(tanA)) - smallRoundR
let angle = CGFloat(M_PI_2 - M_PI_2 * 0.025) + atan(tanA)
if (abs(self.angleLeft - angle) < 0.3 || self.angleLeft == 0){
self.angleLeft = angle
}else{
return
}
}
leftX = centerX - radius * cos(atan(tanA)) - smallRoundR
if(angleLeft >= startAngle && angleLeft <= endAngle){
leftRound?.frame = CGRect(x: leftX, y: leftY, width: smallRoundR * 2, height: smallRoundR * 2)
//change
self.bar?.leftProgress(angleRight: angleRight, angleLeft: angleLeft)
CurrLeftProgress = (angleLeft - startAngle) * maxLeftProgress / (endAngle - startAngle)
if(CurrLeftProgress>100){
CurrLeftProgress = 100
}else if(CurrLeftProgress<0){
CurrLeftProgress = 0
}
}
print("\(TAG) ------->2 CurrLeftProgress \(CurrLeftProgress)")
if(sender.state == UIGestureRecognizerState.began){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}else if(sender.state == UIGestureRecognizerState.changed){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}else if(sender.state == UIGestureRecognizerState.ended){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}
}
}
画图不容易,还是喜欢在纸上用笔胡乱画
长(width) 高(height) 半径(r)
X坐标:± r * cos角度 + width / 2
Y坐标:± r * sin角度 + height / 2
func LeftRoundAction(_ sender: UIPanGestureRecognizer){
if(CurrLeftProgress>=0 && CurrLeftProgress<=100){
let translation = sender.translation(in: self)
if(sender.state == UIGestureRecognizerState.possible){
}else if(sender.state == UIGestureRecognizerState.began){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.changed){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.ended){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
leftEX = translation.x + leftEX
leftEY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.cancelled){
}else if(sender.state == UIGestureRecognizerState.failed){
}else if(sender.state == UIGestureRecognizerState.recognized){
}
//两种情况 y > r or y < r 计算角度 和 新的坐标
var a:CGFloat=0;
var b:CGFloat=0;
if(leftY > centerY){
a = leftY - centerY
b = centerX - leftX
}else{
a = centerX - leftY
b = centerY - leftX
}
let tanA = a / b;
if(leftY > centerY){
leftY = centerY + radius * sin(atan(tanA)) - smallRoundR
let angle = CGFloat(M_PI_2 - M_PI_2 * 0.025) - atan(tanA)
if (abs(self.angleLeft - angle) < 0.3 || self.angleLeft == 0){
self.angleLeft = angle
}else{
return
}
}else{
leftY = centerY - radius * sin(atan(tanA)) - smallRoundR
let angle = CGFloat(M_PI_2 - M_PI_2 * 0.025) + atan(tanA)
if (abs(self.angleLeft - angle) < 0.3 || self.angleLeft == 0){
self.angleLeft = angle
}else{
return
}
}
leftX = centerX - radius * cos(atan(tanA)) - smallRoundR
if(angleLeft >= startAngle && angleLeft <= endAngle){
leftRound?.frame = CGRect(x: leftX, y: leftY, width: smallRoundR * 2, height: smallRoundR * 2)
//change
self.bar?.leftProgress(angleRight: angleRight, angleLeft: angleLeft)
CurrLeftProgress = (angleLeft - startAngle) * maxLeftProgress / (endAngle - startAngle)
if(CurrLeftProgress>100){
CurrLeftProgress = 100
}else if(CurrLeftProgress<0){
CurrLeftProgress = 0
}
}
print("\(TAG) ------->2 CurrLeftProgress \(CurrLeftProgress)")
if(sender.state == UIGestureRecognizerState.began){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}else if(sender.state == UIGestureRecognizerState.changed){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}else if(sender.state == UIGestureRecognizerState.ended){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}
}
}
//
// SeekBarView.swift
// Pacsafe
//
// Created by NOA-Labs on 11/30/16.
// Copyright © 2016 NOA-Labs. All rights reserved.
//
import UIKit
class SeekBarView: UIView {
let TAG:String = "SeekBarView"
@IBOutlet var contentView: UIView!
var gestureRight:UIPanGestureRecognizer? = nil
var gestureLeft:UIPanGestureRecognizer? = nil
var seekbarDelegate:SeekBarViewDelegate? = nil
var leftRound:RoundView?
var rightRound:RoundView?
var bar:BarView?
//小球的半径
let smallRoundR:CGFloat = 21
//起始角度
let startAngle:CGFloat = 0.08
let endAngle:CGFloat = 3.0
//右边的角度
var angleRight:CGFloat = 0
//左边的角度
var angleLeft:CGFloat = 0
//长度
var width:CGFloat = 0
//宽度
var height:CGFloat = 0
var leftX:CGFloat = 0,leftY:CGFloat = 0;
var leftEX:CGFloat = 0,leftEY:CGFloat = 0;
var rightX:CGFloat = 0,rightY:CGFloat = 0;
var rightEX:CGFloat = 0,rightEY:CGFloat = 0;
var centerX:CGFloat = 0,centerY:CGFloat = 0;
var radius:CGFloat = 0
let maxLeftProgress:CGFloat = 100
let maxRightProgress:CGFloat = 100
var CurrLeftProgress:CGFloat = 67
var CurrRightProgress:CGFloat = 70
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initFromXIB()
}
override init(frame: CGRect) {
super.init(frame: frame)
initFromXIB()
}
func initFromXIB() {
let bundle = Bundle(for: type(of: self))
//nibName是你定义的xib文件名
let nib = UINib(nibName: "SeekBarView", bundle: bundle)
contentView = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
contentView.frame = bounds
gestureRight = UIPanGestureRecognizer(target: self, action: #selector(SeekBarView.RightRoundAction))
gestureLeft = UIPanGestureRecognizer(target: self, action: #selector(SeekBarView.LeftRoundAction))
self.addSubview(contentView)
print("\(TAG) -------> initFromXIB \(self.frame)")
// 根据当前的进度 计算应该旋转的角度
angleRight=startAngle + (endAngle - startAngle) / maxRightProgress * CurrRightProgress
angleLeft=startAngle + (endAngle - startAngle) / maxLeftProgress * CurrLeftProgress
}
func RightRoundAction(_ sender: UIPanGestureRecognizer){
if(CurrRightProgress>=0 && CurrRightProgress<=100){
let translation = sender.translation(in: self)
if(sender.state == UIGestureRecognizerState.possible){
}else if(sender.state == UIGestureRecognizerState.began){
rightX = translation.x + rightEX
rightY = translation.y + rightEY
}else if(sender.state == UIGestureRecognizerState.changed){
rightX = translation.x + rightEX
rightY = translation.y + rightEY
}else if(sender.state == UIGestureRecognizerState.ended){
rightX = translation.x + rightEX
rightY = translation.y + rightEY
rightEX = translation.x + rightEX
rightEY = translation.y + rightEY
}else if(sender.state == UIGestureRecognizerState.cancelled){
}else if(sender.state == UIGestureRecognizerState.failed){
}else if(sender.state == UIGestureRecognizerState.recognized){
}
//两种情况 y > r or y < r 计算角度 和 新的坐标
var a:CGFloat=0;
var b:CGFloat=0;
if(rightY > centerY){
a = rightY - centerY
b = rightX - centerX
}else{
a = centerY - rightY
b = rightX - centerX
}
let tanA = a / b;
if(rightY > centerY){
rightY = centerY + radius * sin(atan(tanA)) - smallRoundR
let angle = CGFloat(M_PI_2 - M_PI_2 * 0.025) - atan(tanA)
if (abs(self.angleRight - angle) < 0.3 || self.angleRight == 0){
self.angleRight = angle
}else{
return
}
}else{
rightY = centerY - radius * sin(atan(tanA)) - smallRoundR
let angle = CGFloat(M_PI_2 - M_PI_2 * 0.025) + atan(tanA)
if (abs(self.angleRight - angle) < 0.3 || self.angleRight == 0){
self.angleRight = angle
}else{
return
}
}
rightX = centerX + radius * cos(atan(tanA)) - smallRoundR
if(angleRight >= startAngle && angleRight <= endAngle){
rightRound?.frame = CGRect(x:rightX, y:rightY, width: smallRoundR * 2, height: smallRoundR * 2)
bar?.leftProgress(angleRight: angleRight, angleLeft: angleLeft)
}
CurrRightProgress = (angleRight - startAngle) * maxRightProgress / (endAngle - startAngle)
print("\(TAG) ------->1 CurrRightProgress \(CurrRightProgress)")
if(CurrRightProgress>100){
CurrRightProgress = 100
}else if(CurrRightProgress<0){
CurrRightProgress = 0
}
if(sender.state == UIGestureRecognizerState.began){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.REIGHT, progress: CurrRightProgress)
}else if(sender.state == UIGestureRecognizerState.changed){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.REIGHT, progress: CurrRightProgress)
}else if(sender.state == UIGestureRecognizerState.ended){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.REIGHT, progress: CurrRightProgress)
}
}
}
func LeftRoundAction(_ sender: UIPanGestureRecognizer){
if(CurrLeftProgress>=0 && CurrLeftProgress<=100){
let translation = sender.translation(in: self)
if(sender.state == UIGestureRecognizerState.possible){
}else if(sender.state == UIGestureRecognizerState.began){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.changed){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.ended){
leftX = translation.x + leftEX
leftY = translation.y + leftEY
leftEX = translation.x + leftEX
leftEY = translation.y + leftEY
}else if(sender.state == UIGestureRecognizerState.cancelled){
}else if(sender.state == UIGestureRecognizerState.failed){
}else if(sender.state == UIGestureRecognizerState.recognized){
}
//两种情况 y > r or y < r 计算角度 和 新的坐标
var a:CGFloat=0;
var b:CGFloat=0;
if(leftY > centerY){
a = leftY - centerY
b = centerX - leftX
}else{
a = centerX - leftY
b = centerY - leftX
}
let tanA = a / b;
if(leftY > centerY){
leftY = centerY + radius * sin(atan(tanA)) - smallRoundR
let angle = CGFloat(M_PI_2 - M_PI_2 * 0.025) - atan(tanA)
if (abs(self.angleLeft - angle) < 0.3 || self.angleLeft == 0){
self.angleLeft = angle
}else{
return
}
}else{
leftY = centerY - radius * sin(atan(tanA)) - smallRoundR
let angle = CGFloat(M_PI_2 - M_PI_2 * 0.025) + atan(tanA)
if (abs(self.angleLeft - angle) < 0.3 || self.angleLeft == 0){
self.angleLeft = angle
}else{
return
}
}
leftX = centerX - radius * cos(atan(tanA)) - smallRoundR
if(angleLeft >= startAngle && angleLeft <= endAngle){
leftRound?.frame = CGRect(x: leftX, y: leftY, width: smallRoundR * 2, height: smallRoundR * 2)
//change
self.bar?.leftProgress(angleRight: angleRight, angleLeft: angleLeft)
CurrLeftProgress = (angleLeft - startAngle) * maxLeftProgress / (endAngle - startAngle)
if(CurrLeftProgress>100){
CurrLeftProgress = 100
}else if(CurrLeftProgress<0){
CurrLeftProgress = 0
}
}
print("\(TAG) ------->2 CurrLeftProgress \(CurrLeftProgress)")
if(sender.state == UIGestureRecognizerState.began){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}else if(sender.state == UIGestureRecognizerState.changed){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}else if(sender.state == UIGestureRecognizerState.ended){
self.seekbarDelegate?.fetchChangeProgress(direction: SeekBarViewDirectionStyle.LEFT, progress: CurrLeftProgress)
}
}
}
override func draw(_ rect: CGRect) {
print("\(TAG) ------->2 draw \(self.frame)")
}
override func draw(_ layer: CALayer, in ctx: CGContext) {
self.width = frame.width
self.height = frame.height
// 绘制静态的背景
let progress = ProgressBarView(frame:CGRect.init(x: 0, y: 0, width:self.width, height:self.height))
self.contentView.addSubview(progress)
//根据当前的角度 计算当前的坐标
if(self.width>self.height){
self.radius = self.height / 2
}else{
self.radius = self.width / 2
}
self.leftX = self.width / 2 - self.radius * sin(angleLeft) - smallRoundR
//Y轴需要区分上半部分和下半部分
if(angleLeft<1.504){// 下半部分
self.leftY = self.height / 2 + self.radius * cos(angleLeft + CGFloat(M_PI_2 * 0.025)) - smallRoundR
}else{//上半部分
self.leftY = self.height / 2 - self.radius * cos(CGFloat(M_PI) - angleLeft - CGFloat(M_PI_2 * 0.025)) - smallRoundR
}
self.rightX = self.width / 2 + self.radius * sin(angleRight) - smallRoundR
//Y轴需要区分上半部分和下半部分
if(angleRight<1.504){// 下半部分
self.rightY = self.height / 2 + self.radius * cos(angleRight + CGFloat(M_PI_2 * 0.025)) - smallRoundR
}else{//上半部分
self.rightY = self.height / 2 - self.radius * cos(CGFloat(M_PI) - angleRight - CGFloat(M_PI_2 * 0.025)) - smallRoundR
}
print("\(TAG) ------->1 angleLeft \(self.angleLeft) angleRight:\(angleRight)")
leftEX = leftX
leftEY = leftY
rightEX = rightX
rightEY = rightY
centerY = self.height / 2
centerX = self.width / 2
print("\(TAG) ------->1 frame:\(self.frame)")
// 绘制动态的当前进度
if(bar == nil){
bar = BarView(frame:CGRect.init(x: 0, y: 0, width: self.width, height: self.height))
bar?.setProgress(angleRight:angleRight,angleLeft:angleLeft)
bar?.backgroundColor = UIColor.clear
self.contentView.addSubview(bar!)
}else{
bar?.setProgress(angleRight:angleRight,angleLeft:angleLeft)
}
//draw round
if(leftRound == nil){
leftRound = RoundView(frame:CGRect(x: leftX, y: leftY, width: smallRoundR * 2, height: smallRoundR * 2))
leftRound?.backgroundColor=UIColor.clear
self.addSubview(leftRound!)
leftRound?.isUserInteractionEnabled = true
leftRound?.addGestureRecognizer(gestureLeft!)
}else{
leftRound?.frame = CGRect(x: leftX, y: leftY, width: smallRoundR * 2, height: smallRoundR * 2)
}
if(rightRound == nil){
rightRound = RoundView(frame:CGRect(x: rightX, y: rightY, width: smallRoundR * 2, height: smallRoundR * 2))
self.addSubview(rightRound!)
rightRound?.backgroundColor=UIColor.clear
rightRound?.isUserInteractionEnabled = true
rightRound?.addGestureRecognizer(gestureRight!)
}else{
rightRound?.frame = CGRect(x: rightX, y: rightY, width: smallRoundR * 2, height: smallRoundR * 2)
}
}
}
Android自定义View圆形进度条 Demo下载
[email protected]