2024年Android最全Android自定义控件(状态提示图表)(1),2024年最新被阿里面试官征服了

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

**Android精讲视频学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水!

**任何市场都是优胜略汰适者生存,只要你技术过硬,到哪里都不存在饱和不饱和的问题,所以重要的还是提升自己。懂得多是自己的加分项 而不是必须项。门槛高了只能证明这个市场在不断成熟化!**另外一千个读者就有一千个哈姆雷特,所以以上只是自己的关键,不喜勿喷!

如果你是卡在缺少学习资源的瓶颈上,那么刚刚好我能帮到你。欢迎关注会持续更新和分享的。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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);

}

//设置当前比值

public void updateValues(int x, int y) {

mMeasureXpos = x;

mMeasureYpos = y;

postInvalidate();

}

//设置XY轴顶角的title字体大小

public void setTitleTextSize(int size) {

mXYTitleTextSize = size;

}

//初始化X轴的坐标区间点值,可以不均等分

public void initXLevelOffset(ArrayList list) {

mXLevel.clear();

mXLevel.addAll(list);

}

//初始化Y轴的坐标区间点值,可以不均等分

public void initYLevelOffset(ArrayList list) {

mYLevel.clear();

mYLevel.addAll(list);

}

//初始化每个区间的提示文字,如果不想显示可以设置""

public void initGridLevelText(ArrayList list) {

mGridLevelText.clear();

mGridLevelText.addAll(list);

}

//初始化每个区间的颜色

public void initGridColorLevel(ArrayList list) {

mGridColorLevel.clear();

mGridColorLevel.addAll(list);

}

//初始化每个区间的提示文字颜色

public void initGridTxtColorLevel(ArrayList list) {

mGridTxtColorLevel.clear();

mGridTxtColorLevel.addAll(list);

}

//初始化XY轴title

public void initTitleXY(String x, String y) {

mTitleX = x;

mTitleY = y;

}

}

再来看下布局文件:

<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”>

<com.yanbober.customerviewdemo.areachartsview.AreaChartsView

android:id=“@+id/area_charts_view”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

最后

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

0697150)]

【延伸Android必备知识点】

[外链图片转存中…(img-9MFJSq0q-1714830697150)]

【Android部分高级架构视频学习资源】

Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值