【HarmonyOS】【JAVA UI 】鸿蒙 自定义折线图
关于HarmonyOS 自定义View我们可以学习HarmonyOS自定义组件 这篇文档,今天描述自定义折线图的功能,我们从“准备工作”、“初始化画笔”、“绘画折线图”、“运行效果图”,这四个方面进行描述
1. 准备工作
想要实现折线图我们了解Paint,获取屏幕的宽高,这几个功能的实现
获取屏幕的宽高的代码如下
/** * 获取屏幕宽 * * @param context context * @return int */ public static int getWindowWidth(Context context) { DisplayManager displayManager = DisplayManager.getInstance(); Optional defaultDisplay = displayManager.getDefaultDisplay(context); return defaultDisplay.get().getAttributes().width; } /** * 获取屏幕高 * * @param context context * @return int */ public static int getWindowHeight(Context context) { DisplayManager displayManager = DisplayManager.getInstance(); Optional defaultDisplay = displayManager.getDefaultDisplay(context); return defaultDisplay.get().getAttributes().height; }
2. 初始化画笔
主要实现画笔的设置颜色,设置宽度,设置画笔风格
private void initPaint() { myPaint = new Paint(); myPaint.setColor(defaultColor); myPaint.setStrokeWidth(ringWidth); myPaint.setStyle(Paint.Style.STROKE_STYLE); }
3. 绘画折线图
我们要学会Point,和canvas.drawText, canvas.drawLine绘画Y轴的坐标,绘画x轴坐标,绘画折线图三个方面进行实现
3.1绘画Y轴的坐标代码如下
//Todo 绘画Y轴 //todo 绘画Y线 float mYHeigh = mScreenHeight * mYHeightPercent; Point mYstartPoint = new Point(mYStartPointX, mYStartPointY); Point mYEndPoint = new Point(mYStartPointX, mYHeigh); Line yLine = new Line(mYstartPoint, mYEndPoint); canvas.drawLine(yLine, myPaint);//绘画y线 //TODO 绘画Y轴刻度线 for (int i = 0; i <= 10; i++) { Point mYScalesStartPoint = new Point(mYStartPointX, (mYHeigh - mYStartPointY) * i / 10 + mYStartPointY); Point mYScalesEndPoint = new Point(mYStartPointX + mScaleLength, (mYHeigh - 50) * i / 10 + mYStartPointY); Line yScalesLine = new Line(mYScalesStartPoint, mYScalesEndPoint); canvas.drawLine(yScalesLine, myPaint); //Todo 画Y轴刻度 Paint mPaint = getPaint(); canvas.drawText(mPaint, ((int) (((float) (10 - i) / 10) * 100)) + "", mYStartPointX - 100, (mYHeigh - 50) * i / 10 + mYStartPointY); }
3.2 绘画X轴的坐标代码如下
//Todo 绘画X轴 Point mXstartPoint = new Point(mYStartPointX, mYHeigh); Point mXEndPoint = new Point(mScreenWidth, mYHeigh); Line XLine = new Line(mXstartPoint, mXEndPoint); canvas.drawLine(XLine, myPaint);//绘画x线 //Todo 获取x轴长度 float mXwidth = mScreenWidth - mYStartPointX; //TODO 绘画X轴刻度线 for (int i = 0; i <= 12; i++) { Point mXScalesStartPoint; Point mXScalesEndPoint; mXScalesStartPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh); mXScalesEndPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh - mScaleLength); Line XScalesLine = new Line(mXScalesStartPoint, mXScalesEndPoint); canvas.drawLine(XScalesLine, myPaint); //Todo 画x轴刻度 //Todo 绘画月份 Paint mPaint = getPaint(); mPaint.setTextSize(30); if (i != 0) { canvas.drawText(mPaint, i + "月", mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh + 100); } }
3.3 绘画折线 代码如下
//Todo 绘画折线 Point mXPolyPoint = null; float Percentage = 0f; for (int i = 1; i < myData.length + 1; i++) { if (i == 1) { Percentage = myData[i - 1] / 100f; mXPolyPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh - (float) (mYHeigh - mYStartPointY) * Percentage); } else { Percentage = myData[i - 1] / 100f; Point mNextPolyPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh - (float) (mYHeigh - mYStartPointY) * Percentage); Paint mPaint = getPaint(); mPaint.setColor(Color.RED); mPaint.setTextSize(100); Line mPolyline = new Line(mXPolyPoint, mNextPolyPoint); canvas.drawLine(mPolyline, mPaint);//绘画两个月份点之间连线 mXPolyPoint = mNextPolyPoint; } }
4. 运行效果
4.1全部代码如下
package com.harmony.alliance.mydemo.view;import ohos.agp.components.AttrSet;import ohos.agp.components.Component;import ohos.agp.render.Canvas;import ohos.agp.render.Paint;import ohos.agp.utils.Color;import ohos.agp.utils.Line;import ohos.agp.utils.Point;import ohos.agp.window.service.Display;import ohos.agp.window.service.DisplayManager;import ohos.app.Context;import java.util.Optional; public class CustomComponent extends Component implements Component.DrawTask { private Paint myPaint; private Color defaultColor = new Color(Color.rgb(237, 98, 98)); //画笔的宽度 private float ringWidth = 10; private int mScreenWidth;//屏幕宽度 private int mScreenHeight;//屏幕高度 private float mYHeightPercent = 0.8f;//Y轴百分比 //todo Y轴起始点坐标x点 private float mYStartPointX = 200; //todo Y轴起始点坐标y点 private float mYStartPointY = 50; private float mScaleLength = 50; private int[] myData = new int[]{68, 10, 45, 10, 88, 63, 60, 55, 79, 34, 52, 77}; public CustomComponent(Context context) { this(context, null); } //如需支持xml创建自定义组件,必须添加该构造方法 public CustomComponent(Context context, AttrSet attrSet) { super(context, attrSet); //todo 获取屏幕宽高 mScreenWidth = getWindowWidth(context); mScreenHeight = getWindowHeight(context); // 初始化画笔 initPaint(); // 添加绘制任务 addDrawTask(this); } private void initPaint() { myPaint = new Paint(); myPaint.setColor(defaultColor); myPaint.setStrokeWidth(ringWidth); myPaint.setStyle(Paint.Style.STROKE_STYLE); } @Override public void onDraw(Component component, Canvas canvas) { //Todo 绘画Y轴 //todo 绘画Y线 float mYHeigh = mScreenHeight * mYHeightPercent; Point mYstartPoint = new Point(mYStartPointX, mYStartPointY); Point mYEndPoint = new Point(mYStartPointX, mYHeigh); Line yLine = new Line(mYstartPoint, mYEndPoint); canvas.drawLine(yLine, myPaint);//绘画y线 //TODO 绘画Y轴刻度线 for (int i = 0; i <= 10; i++) { Point mYScalesStartPoint = new Point(mYStartPointX, (mYHeigh - mYStartPointY) * i / 10 + mYStartPointY); Point mYScalesEndPoint = new Point(mYStartPointX + mScaleLength, (mYHeigh - 50) * i / 10 + mYStartPointY); Line yScalesLine = new Line(mYScalesStartPoint, mYScalesEndPoint); canvas.drawLine(yScalesLine, myPaint); //Todo 画Y轴刻度 Paint mPaint = getPaint(); canvas.drawText(mPaint, ((int) (((float) (10 - i) / 10) * 100)) + "", mYStartPointX - 100, (mYHeigh - 50) * i / 10 + mYStartPointY); } //Todo 绘画X轴 Point mXstartPoint = new Point(mYStartPointX, mYHeigh); Point mXEndPoint = new Point(mScreenWidth, mYHeigh); Line XLine = new Line(mXstartPoint, mXEndPoint); canvas.drawLine(XLine, myPaint);//绘画x线 //Todo 获取x轴长度 float mXwidth = mScreenWidth - mYStartPointX; //TODO 绘画X轴刻度线 for (int i = 0; i <= 12; i++) { Point mXScalesStartPoint; Point mXScalesEndPoint; mXScalesStartPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh); mXScalesEndPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh - mScaleLength); Line XScalesLine = new Line(mXScalesStartPoint, mXScalesEndPoint); canvas.drawLine(XScalesLine, myPaint); //Todo 画x轴刻度 //Todo 绘画月份 Paint mPaint = getPaint(); mPaint.setTextSize(30); if (i != 0) { canvas.drawText(mPaint, i + "月", mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh + 100); } } //Todo 绘画折线 Point mXPolyPoint = null; float Percentage = 0f; for (int i = 1; i < myData.length + 1; i++) { if (i == 1) { Percentage = myData[i - 1] / 100f; mXPolyPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh - (float) (mYHeigh - mYStartPointY) * Percentage); } else { Percentage = myData[i - 1] / 100f; Point mNextPolyPoint = new Point(mYStartPointX + (mXwidth - mScaleLength) / 12 * i, mYHeigh - (float) (mYHeigh - mYStartPointY) * Percentage); Paint mPaint = getPaint(); mPaint.setColor(Color.RED); mPaint.setTextSize(100); Line mPolyline = new Line(mXPolyPoint, mNextPolyPoint); canvas.drawLine(mPolyline, mPaint);//绘画两个月份点之间连线 mXPolyPoint = mNextPolyPoint; } } } /** * 获取屏幕宽 * * @param context context * @return int */ public static int getWindowWidth(Context context) { DisplayManager displayManager = DisplayManager.getInstance(); Optional defaultDisplay = displayManager.getDefaultDisplay(context); return defaultDisplay.get().getAttributes().width; } /** * 获取屏幕高 * * @param context context * @return int */ public static int getWindowHeight(Context context) { DisplayManager displayManager = DisplayManager.getInstance(); Optional defaultDisplay = displayManager.getDefaultDisplay(context); return defaultDisplay.get().getAttributes().height; } //初始化刻度线的画笔 public Paint getPaint() { Paint paint = new Paint(); paint.setColor(Color.RED); paint.setTextSize(50); return paint; }}
4.2新建AbilitySlice 然后在xml布局中写如下代码
4.3运行效果图
更多相关学习资料:
https://developer.huawei.com/consumer/cn/forum/topic/0201773829654680176?fid=0102683795438680754?ha_source=zzh