一、ECharts的折线图
ECharts
相信大家都见识过其强大,那么android和Flutter能否达到如此的效果呢?毫无疑问,自定义绘制无所不能,接下来我们逐渐的深入到移动端自定义中,去搞定ECharts
中的精美的折线图
、饼图
、散列点
、K线图
、雷达图
、关系图
等…
1.
2.
3.
4.
二、Android和Flutter中涉及到的知识
0.
Canvas画布的变换
和状态保存
1.Android自定义中绘制折线
相关API
2.Android中绘制圆圈
3.文字的绘制
4.基本动画的使用。
5.绘制中Path的测量
1.相关API
更详细API看API介绍章节
/**弧度类相关API**/
(cx,cy)为坐标,radius为半径在画布中进行画圆。画笔作为填充或描边
public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
/**状态相关API**/
保存当前的矩阵画布到堆栈里面后面再用。
save()
保存当前状态成副本形成组
public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint, @Saveflags int saveFlags)
该调用平衡了对save()的先前调用,并用于删除自上次保存调用以来对矩阵/剪辑状态的所有修改。
public void restore()
/**设置画布变换**/
设置画布平移
public void translate(float dx, float dy)
画布缩放
public void scale(float sx, float sy)
画布旋转
public void rotate(float degrees)
设置背景色
canvas.drawColor()
/**绘制点线段**/
将下一个轮廓的起点设置为点(x,y)
public void moveTo(float x, float y)
设置相对于上一个轮廓的最后一个点为相对位置下一个轮廓的起点。如果没有先前的轮廓就于moveTo()相同。
public void rMoveTo(float dx, float dy)
将坐标视为相对于此轮廓上的最后一点。如果没有先前的点,就同moveTo(0,0)
public void LineTo(float x, float y)
与lineTo相同,但是将坐标视为相对于此轮廓上的最后一点。如果没有先前的点,就同moveTo(0,0)
public void rLineTo(float dx, float dy)
/**给当前的路径添加形状路径**/
public void addCircle(float x, float y, float radius, @NonNull Direction dir)
/**画布上绘制文字**/
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint)
....
2.🌟🌟⭐️画布变换🌟🌟⭐️
画布的变换和快照堆栈保存会贯穿
整个绘制过程
和所有章节
,所以我们必须重点讲解。首先我们将Activity设置为横屏,新建一个自定义类LHC_Line_broken。
class LHC_BrokenLine_View @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : View(context, attrs, defStyle) {
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
}
}
在MainActivity中增加横屏代码
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
1.绘制圆
在坐标(x,y)=(0,0)处利用
canvas.drawCircle(...)
绘制半径为200px,画笔为填充蓝色的圆。
(cx,cy)为坐标,radius为半径在画布中进行画圆。画笔作为填充或描边
public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint)
绘制代码
class LHC_BrokenLine_View @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : View(context, attrs, defStyle) {
@SuppressLint("DrawAllocation")
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
//初始化画笔
val ciclePaint=Paint()
//画笔为填充闭合路径区域
ciclePaint.style= Paint.Style.FILL
ciclePaint.color= Color.BLUE
ciclePaint.isAntiAlias=true
//绘制圆圈
canvas.drawCircle(0f,0f,200f,ciclePaint)
}
}
运行结果为圆的四分之一,默认画布屏幕左上角(0,0)为坐标原点x轴右边为正,y轴向下为正,我们绘制的圆应该屏幕遮挡所以看不到,实际效果应该是图2。
1.
2.
2.画布translate[平移]
- 我们将画布Canvas坐标系向下平移400px。然后再绘制一个同样的圆。我们来线分析一下,再看效果。坐标系默认在横屏的左上角,然后绘制圆【四分之一】,向下平移画布400px,画布坐标系如图中3,最后绘制同样的圆如四但是由于屏幕遮挡原因,只能看到半个圆圈。
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
//初始化画笔
val ciclePaint=Paint()
ciclePaint.style= Paint.Style