




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】如何使用kotlin实现一个饼图
先看看做的是什么/upload/information/20200623/125/125049.jpg知识点/upload/information/20200623/125/125050.jpg绘制饼图
public
void
drawArc(float
left,
float
top,
float
right,
float
bottom,
float
startAngle,
float
sweepAngle,
boolean
useCenter,
@NonNull
Paint
paint)
{
super.drawArc(left,
top,
right,
bottom,
startAngle,
sweepAngle,
useCenter,
paint);
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override
fun
onDraw(canvas:
Canvas)
{
super.onDraw(canvas)
canvas.drawArc(0f,
0f,
width,
height,
0f,
360f,
true,
paintRed)
}/upload/information/20200623/125/125051.jpg
/**
*
view的宽度
*/
var
width:
Float
=
0f
/**
*
view的高度
*/
var
height:
Float
=
0f
/**
*
drawArc距离左边的距离
*/
var
left:
Float
=
0f
/**
*
drawArc距离上边的距离
*/
var
top:
Float
=
0f
/**
*
drawArc距离右边的距离
*/
var
right:
Float
=
0f
/**
*
drawArc距离下边的距离
*/
var
bottom:
Float
=
0f
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override
fun
onDraw(canvas:
Canvas)
{
super.onDraw(canvas)
canvas.drawArc(left,
top,
right,
bottom,
0f,
360f,
true,
paint)
}
override
fun
onSizeChanged(w:
Int,
h:
Int,
oldw:
Int,
oldh:
Int)
{
super.onSizeChanged(w,
h,
oldw,
oldh)
setBackgroundColor(resources.getColor(R.color.black))
width
=
w.toFloat()
height
=
h.toFloat()
left
=
width
/
4f
top
=
width
/
4f
right
=
width
-
left
bottom
=
width
-
top
}/upload/information/20200623/125/125052.jpg
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override
fun
onDraw(canvas:
Canvas)
{
super.onDraw(canvas)
...
canvas.drawArc(left,
top,
right,
bottom,
0f,
20f,
true,
paintPuple)
canvas.drawArc(left,
top,
right,
bottom,
20f,
10f,
true,
paintGray)
canvas.drawArc(left,
top,
right,
bottom,
30f,
40f,
true,
paintGreen)
canvas.drawArc(left,
top,
right,
bottom,
70f,
110f,
true,
paintBlue)
canvas.drawArc(left,
top,
right,
bottom,
180f,
110f,
true,
paintRed)
canvas.drawArc(left,
top,
right,
bottom,
290f,
70f,
true,
paintYellow)
}
/**
*
个人分类集合
*/
var
pieList
=
arrayListOf(10f,3f,7f)
/**
*
饼图所占的比例
*/
var
scaleList
=
arrayListOf<Float>()
/**
*
个数分类的总量
*/
var
total:
Float
=
0f
override
fun
onSizeChanged(w:
Int,
h:
Int,
oldw:
Int,
oldh:
Int)
{
super.onSizeChanged(w,
h,
oldw,
oldh)
//计算个数的总和
total
=
pieList.sum()
//存储比例值
for
(a
in
pieList)
{
scaleList.add(a.div(total))
}
}
/**
*
记录当前画饼图的度数
*/
var
currentDegree:
Float
=
0f
/**
*
累加饼图的度数作为下一个绘制的起始度数
*/
var
srctorDegree:
Float
=
0f
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override
fun
onDraw(canvas:
Canvas)
{
super.onDraw(canvas)
for
(scale
in
scaleList)
{
val
paint
=
Paint()
paint.strokeWidth
=
dip(10.0f).toFloat()
paint.isAntiAlias
=
true
//定义一个随机生成的颜色数,来区分不同的扇形区域
val
hex
=
"#"
+
Integer.toHexString((-16777216
*
Math.random()).toInt())
paint.color
=
Color.parseColor(hex)
//角度数
srctorDegree
=
scale
*
360
canvas.drawArc(left,
top,
right,
bottom,
currentDegree,
srctorDegree,
true,
paint)
//累加角度
currentDegree
+=
srctorDegree
}
}/upload/information/20200623/125/125053.jpg绘制折线
...
canvas.drawArc(left,
top,
right,
bottom,
currentDegree,
srctorDegree,
true,
paint)
val
path
=
Path()
path.arcTo(left,
top,
right,
bottom,
currentDegree
+
srctorDegree
/
2,
0f,
false)
...
val
bounds
=
RectF()
//将path当前的坐标赋值给bounds
puteBounds(bounds,
true)
/**
*
横线的长度
*/
var
lineae:
Int
=
30
/**
*
斜线的长度
*/
var
slantLine:
Int
=
30
override
fun
onSizeChanged(w:
Int,
h:
Int,
oldw:
Int,
oldh:
Int)
{
super.onSizeChanged(w,
h,
oldw,
oldh)
//计算横线的比例
lineae
=
(width
/
30f).toInt()
//计算斜线的比例
slantLine
=
(width
/
40f).toInt()
}
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override
fun
onDraw(canvas:
Canvas)
{
super.onDraw(canvas)
for
(scale
in
scaleList)
{
...
val
path
=
Path()
path.arcTo(left,
top,
right,
bottom,
currentDegree
+
srctorDegree
/
2,
0f,
false)
val
bounds
=
RectF()
puteBounds(bounds,
true)
//第一象限
if
(bounds.left
>=
width
/
2
&&
bounds.top
<=
width
/
2)
{
path.lineTo(bounds.left
+
lineae,
bounds.top)
path.lineTo(bounds.left
+
lineae
+
slantLine,
bounds.top
-
slantLine)
canvas.drawPath(path,
paintLine)
//第二象限
}
else
if
(bounds.left
<=
width
/
2
&&
bounds.top
<=
width
/
2)
{
path.lineTo(bounds.left
-
lineae,
bounds.top)
path.lineTo(bounds.left
-
lineae
-
slantLine,
bounds.top
-
slantLine)
canvas.drawPath(path,
paintLine)
//第三象限
}
else
if
(bounds.left
<=
width
/
2
&&
bounds.top
>=
width
/
2)
{
path.lineTo(bounds.left
-
lineae,
bounds.top)
path.lineTo(bounds.left
-
lineae
-
slantLine,
bounds.top
+
slantLine)
canvas.drawPath(path,
paintLine)
//第四象限
}
else
{
path.lineTo(bounds.left
+
lineae,
bounds.top)
path.lineTo(bounds.left
+
lineae
+
slantLine,
bounds.top
+
slantLine)
canvas.drawPath(path,
paintLine)
}
}
...
}/upload/information/20200623/125/125054.jpg绘制文字接下来就是绘制文字了,第一、四象限还好,文字可以在折线后面跟着画,但是二、三象限的文字就不允许了,我们必须往前移动文字宽度的距离才能完美衔接到折线上,所以,我们来定义一个计算文字的方法
/**
*
获取文字的宽度
*/
private
fun
getStringWidth(str:
String):
Float
=
paintLine.measureText(str)
paintLine.textSize
=
dip(width
/
100).toFloat()
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override
fun
onDraw(canvas:
Canvas)
{
super.onDraw(canvas)
...
//获取当前的百分比文字
val
textStr
=
String.format("%.2f%%",
scale
*
100)
//获取文字的宽度
val
textWidth
=
getStringWidth(textStr)
//第一象限
if
(bounds.left
>=
width
/
2
&&
bounds.top
<=
width
/
2)
{
...
canvas.drawText(textStr,
bounds.left
+
lineae
+
slantLine,
bounds.top
-
slantLine,
paintText)
...
//第二象限
}
else
if
(bounds.left
<=
width
/
2
&&
bounds.top
<=
width
/
2)
{
...
canvas.drawText(textStr,
bounds.left
-
lineae
-
slantLine
-
textWidth,
bounds.top
-
slantLine,
paintText)
...
//第三象限
}
else
if
(bounds.left
<=
width
/
2
&&
bounds.top
>=
width
/
2)
{
...
canvas.drawText(textStr,
bounds.left
-
lineae
-
slantLine
-
textWidth,
bounds.top
+
lineae,
paintText)
...
//第四象限
}
else
{
...
canvas.drawText(textStr,
bounds.left
+
lineae
+
slantLine,
bounds.top
+
slantLine,
paintText)
...
}
}/upload/information/20200623/125/125055.jpg
//定义中间黑圆的画笔
paintCicle.color
=
resources.getColor(R.color.black)
paintCicle.isAntiAlias
=
true
paintCicle.style
=
Paint.Style.FILL
@RequiresApi(Build.
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025国网冀北电力有限公司第二批高校毕业生录用人选的模拟试卷及完整答案详解一套
- 2025年安徽国风新材料股份有限公司秋季招聘37人考试模拟试题及答案解析
- 2025江苏省启东实验小学招聘水电工1人考前自测高频考点模拟试题含答案详解
- 2025曲江教师招聘试题及答案
- 2025云南玉溪易门县委社会工作部招聘办公辅助人员2人备考考试题库附答案解析
- 萍乡市安源区2025年面向社会公开招聘社区工作者【11人】备考考试题库附答案解析
- 2025云南昭通彝良县医共体总医院招聘编外专业技术人员和村医22人考试参考题库及答案解析
- 2025重庆市巴南区事业单位2025年面向“三支一扶”人员招聘7人考试参考试题及答案解析
- 2025益阳会计单招试题及答案
- 2025广东惠州博罗县中医医院招聘专业技术人员45人(第三批)备考考试题库附答案解析
- (安徽卷)2025年高考历史试题
- PI-DataLink软件基础操作培训教程
- 关爱弱势群体课件
- 校企挂职锻炼协议书范本
- 驾照换证考试题库及答案
- 医药物流仓库管理流程标准
- 2025至2030鸡汁行业风险投资态势及投融资策略指引报告
- (高清版)DB31∕T 1578-2025 微型消防站建设与运行要求
- 儿童百日咳的诊治
- 40篇英语短文搞定高考3500个单词(全部含翻译,重点解析)
- 江苏艺考笔试题及答案
评论
0/150
提交评论