【HarmonyOS】【JAVA UI】鴻蒙 自定義折線圖
阿新 • • 發佈:2022-03-23
關於HarmonyOS 自定義View我們可以學習HarmonyOS自定義元件 這篇文件,今天描述自定義折線圖的功能,我們從“準備工作”、“初始化畫筆”、“繪畫折線圖”、“執行效果圖”,這四個方面進行描述
1. 準備工作
想要實現折線圖我們瞭解Paint,獲取螢幕的寬高,這幾個功能的實現
獲取螢幕的寬高的程式碼如下
/** * 獲取螢幕寬 * * @param context context * @return int */ public static int getWindowWidth(Context context) { DisplayManager displayManager = DisplayManager.getInstance(); Optional<Display> 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<Display> 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<Display> 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<Display> 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佈局中寫如下程式碼
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical">
<com.harmony.alliance.mydemo.view.CustomComponent
ohos:width="match_parent"
ohos:height="match_parent">
</com.harmony.alliance.mydemo.view.CustomComponent>
</DirectionalLayout>
4.3 執行效果圖