private int mWidth, mHight;

private int mRealWidth, mRealHight;

private String mTitleY, mTitleX;

private ArrayList mXLevel = new ArrayList<>();

private ArrayList mYLevel = new ArrayList<>();

private ArrayList mGridLevelText = new ArrayList<>();

private ArrayList mGridColorLevel = new ArrayList<>();

private ArrayList mGridTxtColorLevel = new ArrayList<>();

private int mGridLevel = mXLevel.size() - 1;

//title字符大小

private int mXYTitleTextSize = 40;

private int mMeasureXpos, mMeasureYpos;

public AreaChartsView(Context context, AttributeSet attrs) {

super(context, attrs);

mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

mPaint.setAntiAlias(true);

mPaint.setFilterBitmap(true);

}

@Override

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

super.onLayout(changed, left, top, right, bottom);

mWidth = getWidth();

mHight = getHeight();

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

initPosition();

drawXYTitle(canvas);

drawXYLine(canvas);

drawContent(canvas);

}

private void initPosition() {

//初始化坐标图的xy交点原点坐标

mZeroPos[0] = mXYTitleTextSize * 2;

mZeroPos[1] = mHight - mXYTitleTextSize * 4;

//初始化坐标图的X轴最大值坐标

mMaxXPos[0] = mWidth;

mMaxXPos[1] = mHight - mXYTitleTextSize * 4;

//初始化坐标图的Y轴最大值坐标

mMaxYPos[0] = mXYTitleTextSize * 2;

mMaxYPos[1] = mXYTitleTextSize * 2;

}

private void drawXYTitle(Canvas canvas) {

mPaint.setColor(Color.parseColor(“#1FB0E7”));

mPaint.setTextSize(mXYTitleTextSize);

mPaint.setTextAlign(Paint.Align.LEFT);

//画Y轴顶的title

canvas.drawText(mTitleY, mMaxYPos[0] - mXYTitleTextSize * 2, mMaxYPos[1] - mXYTitleTextSize, mPaint);

mPaint.setTextAlign(Paint.Align.RIGHT);

//画X轴顶的title

canvas.drawText(mTitleX, mMaxXPos[0], mMaxXPos[1] + mXYTitleTextSize * 2, mPaint);

}

private void drawXYLine(Canvas canvas) {

mPaint.setColor(Color.DKGRAY);

mPaint.setTextAlign(Paint.Align.RIGHT);

//画XY轴

canvas.drawLine(mMaxYPos[0], mMaxYPos[1], mZeroPos[0], mZeroPos[1], mPaint);

canvas.drawLine(mZeroPos[0], mZeroPos[1], mMaxXPos[0], mMaxXPos[1], mPaint);

}

private void drawContent(Canvas canvas) {

mGridLevel = mXLevel.size() - 1;

//计算出偏移title等显示尺标后的真实XY轴长度,便于接下来等分

mRealWidth = (mWidth - mXYTitleTextSize * 2);

mRealHight = (mHight - mXYTitleTextSize * 4);

//算出等分间距

int offsetX = mRealWidth/(mGridLevel);

int offsetY = mRealHight/(mGridLevel+1);

//循环绘制content

for (int index=0; index<mGridLevel+1; index++) {

mPaint.setColor(Color.DKGRAY);

mPaint.setTextAlign(Paint.Align.RIGHT);

mPaint.setTextSize(mXYTitleTextSize-5);

//绘制X轴的那些坐标区间点,包含0点坐标

canvas.drawText(String.valueOf(mXLevel.get(index)), mZeroPos[0]+(index*offsetX), mZeroPos[1] + mXYTitleTextSize, mPaint);

if (index != 0) {

//绘制Y轴坐标区间点,不包含0点坐标,X轴已经画过了

canvas.drawText(String.valueOf(mYLevel.get(index)), mZeroPos[0], mZeroPos[1]-(index*offsetY), mPaint);

}

if (index == mGridLevel) {

//坐标区间 = 真实区间 + 1

break;

}

mPaint.setColor(mGridColorLevel.get(mGridLevel - 1 - index));

mPaint.setStyle(Paint.Style.FILL);

//绘制区间叠加图谱方块,从远到0坐标,因为小的图会覆盖大的图

canvas.drawRect(mMaxYPos[0], mMaxYPos[1] + indexoffsetY, mMaxXPos[0]-indexoffsetX, mMaxXPos[1], mPaint);

mPaint.setColor(mGridTxtColorLevel.get(index));

mPaint.setTextAlign(Paint.Align.RIGHT);

mPaint.setTextSize(mXYTitleTextSize);

//绘制每个方块状态区间的提示文字

canvas.drawText(mGridLevelText.get(index), mMaxXPos[0] - index * offsetX - mXYTitleTextSize,

mMaxYPos[1] + index * offsetY + mXYTitleTextSize, mPaint);

}

//绘制当前坐标

drawNotice(canvas, offsetX, offsetY);

}

private void drawNotice(Canvas canvas, int offsetX, int offsetY) {

int realPosX = 0;

int realPosY = 0;

//计算传入的x值与真实屏幕坐标的像素值的百分比差值转换

for (int index=0; index<mGridLevel; index++) {

if (mMeasureXpos >= mXLevel.get(index) && mMeasureXpos < mXLevel.get(index+1)) {

int subValue = mMeasureXpos - mXLevel.get(index);

int offset = mXLevel.get(index+1) - mXLevel.get(index);

realPosX = mZeroPos[0] + index*offsetX + (subValue / offset);

break;

}

}

//计算传入的y值与真实屏幕坐标的像素值的百分比差值转换

for (int index=0; index<mGridLevel; index++) {

if (mMeasureYpos >= mYLevel.get(index) && mMeasureYpos < mYLevel.get(index+1)) {

int subValue = mMeasureYpos - mYLevel.get(index);

int offset = mYLevel.get(index+1) - mYLevel.get(index);

realPosY = mZeroPos[1] - index*offsetY - (offsetY - (subValue / offset));

break;

}

}

//画我们传入的坐标点的标记小红点

mPaint.setColor(Color.RED);

mPaint.setStyle(Paint.Style.FILL);

canvas.drawCircle(realPosX, realPosY, 8, mPaint);

int[] centerPos = {mZeroPos[0] + mRealWidth/2, mZeroPos[1] - mRealHight/2};

mPaint.setColor(Color.WHITE);

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

RectF rectF = null;

Path path = new Path();

//画红点旁边的提示框和文字,有四个区域,然后提示框的小三角指标方位不同

if (realPosX <= centerPos[0] && realPosY >= centerPos[1]) {

//left-bottom

//画三角形

path.moveTo(realPosX+5, realPosY+5);

path.lineTo(realPosX+15, realPosY+15);

path.lineTo(realPosX+15, realPosY-15);

//画矩形背景

rectF = new RectF(realPosX+15, realPosY-40, realPosX+200, realPosY + 30);

canvas.drawRoundRect(rectF, 15, 15, mPaint);

//画提示框的文字

mPaint.reset();

mPaint.setColor(Color.RED);

mPaint.setTextSize(mXYTitleTextSize - 5);

canvas.drawText(“(”+mMeasureXpos+“, “+mMeasureYpos+”)”, realPosX+30, realPosY, mPaint);

}

else if (realPosX <= centerPos[0] && realPosY < centerPos[1]) {

//left-top

path.moveTo(realPosX+5, realPosY+5);

path.lineTo(realPosX+15, realPosY+15);

path.lineTo(realPosX + 15, realPosY - 15);

rectF = new RectF(realPosX+15, realPosY - 20, realPosX+200, realPosY + 50);

canvas.drawRoundRect(rectF, 15, 15, mPaint);

mPaint.reset();

mPaint.setColor(Color.RED);

mPaint.setTextSize(mXYTitleTextSize - 5);

canvas.drawText(“(”+mMeasureXpos+“, “+mMeasureYpos+”)”, realPosX+30, realPosY+20, mPaint);

}

else if (realPosX > centerPos[0] && realPosY >= centerPos[1]) {

//right-bottom

path.moveTo(realPosX-5, realPosY+5);

path.lineTo(realPosX-15, realPosY+15);

path.lineTo(realPosX - 15, realPosY - 15);

rectF = new RectF(realPosX-200, realPosY-40, realPosX-15, realPosY + 30);

canvas.drawRoundRect(rectF, 15, 15, mPaint);

mPaint.reset();

mPaint.setColor(Color.RED);

mPaint.setTextSize(mXYTitleTextSize - 5);

canvas.drawText(“(”+mMeasureXpos+“, “+mMeasureYpos+”)”, realPosX-180, realPosY, mPaint);

}

else if (realPosX > centerPos[0] && realPosY < centerPos[1]) {

//right-top

path.moveTo(realPosX-5, realPosY+5);

path.lineTo(realPosX-15, realPosY+15);

path.lineTo(realPosX - 15, realPosY - 15);

rectF = new RectF(realPosX-200, realPosY - 20, realPosX-15, realPosY + 50);

canvas.drawRoundRect(rectF, 15, 15, mPaint);

mPaint.reset();

mPaint.setColor(Color.RED);

mPaint.setTextSize(mXYTitleTextSize - 5);

canvas.drawText(“(”+mMeasureXpos+“, “+mMeasureYpos+”)”, realPosX-180, realPosY+30, mPaint);

}

path.close();

mPaint.setColor(Color.WHITE);

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

canvas.drawPath(path, mPaint);

}

最后

本文在开源项目GitHub中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

目前已经更新的部分资料,需要的自己取:



自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-kYTwYWTm-1710963642440)]
[外链图片转存中…(img-JTT4F0kN-1710963642441)]
[外链图片转存中…(img-6urwChyk-1710963642441)]
[外链图片转存中…(img-TRoajnUN-1710963642442)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-r3BDkoxn-1710963642442)]

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐