1.画笔模式
/**
* Set the paint's style, used for controlling how primitives'
* geometries are interpreted (except for drawBitmap, which always assumes
* Fill).
*
* @param style The new style to set in the paint
*/
public void setStyle(Style style) {
nSetStyle(mNativePaint, style.nativeInt);
}
Paint.Style.STROKE描边Paint.Style.FILL填充Paint.Style.FILL_AND_STROKE同时填充和描边
2.线冒样式
/**
* Set the paint's Cap.
*
* @param cap set the paint's line cap style, used whenever the paint's
* style is Stroke or StrokeAndFill.
*/
public void setStrokeCap(Cap cap) {
nSetStrokeCap(mNativePaint, cap.nativeInt);
}
Paint.Cap.BUTT:笔画以小路为终点,不向外投射。Paint.Cap.SQUARE:笔画突出为一个正方形,中心位于路径的末端。Paint.Cap.ROUND: 笔画以半圆的形式伸出,中心位于路径的末端
3.打造炫酷进度条
class CircleView @JvmOverloads constructor(
context: Context,
attr: AttributeSet? = null,
defStyle: Int = 0
) :
View(context, attr, defStyle) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val isWrap = (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST ||MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST)
val size = if (isWrap) {
40
} else {
val width = MeasureSpec.getSize(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
min(width, height)
}
setMeasuredDimension(size, size)
}
private val bluePaint by lazy {
Paint().apply {
color = Color.BLUE
isAntiAlias = true
strokeWidth = borderWith
//设置画笔仅描边,不填充
style = Paint.Style.STROKE
}
}
private val redPaint by lazy {
Paint().apply {
color = Color.RED
isAntiAlias = true
strokeWidth = borderWith
//设置画笔仅描边,不填充
style = Paint.Style.STROKE
//两端为圆形
strokeCap = Paint.Cap.ROUND
}
}
private val textPaint by lazy {
Paint().apply {
color = Color.BLUE
isAntiAlias = true
textSize = borderWith
}
}
private val borderWith = 20F
private val circleRectF by lazy {
val leftAndTop = borderWith / 2
val rightAndBottom = width - borderWith / 2
RectF(leftAndTop, leftAndTop, rightAndBottom, rightAndBottom)
}
private val textRect by lazy { Rect() }
private var currentProgress = 0.59F
override fun draw(canvas: Canvas) {
super.draw(canvas)
val circleRange=360F
canvas.drawArc(circleRectF, 0F, circleRange, false, bluePaint)
val content = if (currentProgress in 0F..1F) {
"${(currentProgress * 100).toInt()}"
} else {
"0"
} + "%"
textPaint.getTextBounds(content, 0, content.length, textRect)
val x = (width / 2 - textRect.width() / 2).toFloat()
val dy = with(textPaint.fontMetricsInt) {
(bottom - top) / 2 - bottom
}
val baseLine = (height / 2 + dy).toFloat()
canvas.drawText(content, x, baseLine, textPaint)
canvas.drawArc(circleRectF, 0F, circleRange*currentProgress, false, redPaint)
}
fun refreshProgress(currentProgress:Float){
this.currentProgress=currentProgress
invalidate()
}
}
4.仿58同城数据加载效果(此处为等边三角形)
此处是真正的等边三角形三条边都相等
绝非是常见的,想当然的,网上流传甚广的这种情况
private val path by lazy {
with(Path()) {
moveTo((width / 2).toFloat(), 0F)
lineTo(0F, height.toFloat())
lineTo(width.toFloat(), height.toFloat())
close()
this
}
}
class RandomView @JvmOverloads constructor(
context: Context,
attr: AttributeSet? = null,
defStyle: Int = 0
) :
View(context, attr, defStyle) {
enum class RefreshType {
Circle, Rect, Triangle
}
private var showType: RefreshType = RefreshType.Circle
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val isWrap = (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) || (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST)
val size = if (isWrap) {
300
} else {
min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec))
}
setMeasuredDimension(size, size)
}
private val colorPaint by lazy { Paint() }
private val rect by lazy { Rect(0, 0, width, height) }
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
when (showType) {
RefreshType.Circle -> {
colorPaint.color=Color.BLUE
//画圆
val center = (width / 2).toFloat()
canvas.drawCircle(center, center, center, colorPaint)
}
//画正方形
RefreshType.Rect -> {
colorPaint.color=Color.RED
canvas.drawRect(rect, colorPaint)
}
//画三角形
RefreshType.Triangle -> {
colorPaint.color=Color.GREEN
canvas.drawPath(path, colorPaint)
}
}
}
/**
* 根据直角三角形:a^2+b^=c^2(斜边)
*
* 等边三角形底边做垂直线可得到:
*
* 两个相等的30°,60°的RT(right triangle)直角三角形
*
* 斜边为等边三角形的边
* 底边为(等边三角形的边/2)
* 直角边为等边三角形的垂直线
* */
private val path by lazy {
with(Path()) {
moveTo((width / 2).toFloat(), 0F)
//斜边的平方
val hypotenuse= width.toDouble().pow(2)
//底边的平方
val bottom=(width/2).toDouble().pow(2)
//直角边开平方
val vertical=sqrt(hypotenuse-bottom).toFloat()
lineTo(0F, vertical)
lineTo(width.toFloat(),vertical)
close()
this
}
}
/**
* 内部切换更好
* */
fun refreshShowType() {
showType=when(showType){
RefreshType.Circle->RefreshType.Rect
RefreshType.Rect->RefreshType.Triangle
RefreshType.Triangle->RefreshType.Circle
}
invalidate()
}
}