關于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 = https://www.cnblogs.com/developer-huawei/archive/2022/03/23/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:
ohos:alignment="center"
ohos:orientation="vertical">
<com.harmony.alliance.mydemo.view.CustomComponent
ohos:
ohos:height="match_parent">
</com.harmony.alliance.mydemo.view.CustomComponent>
</DirectionalLayout>
4.3 運行效果圖

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/448181.html
標籤:其他
上一篇:【FAQ】關于分析服務錯誤獲取所選日期前一天事件資料的解決方法
下一篇:org.openqa.selenium.SessionNotCreatedException:訊息:無法啟動新會話。使用SeleniumJava的回應代碼500錯誤
