总结
最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Path.java
public void addArc(RectF oval, float startAngle, float sweepAngle) {
addArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle);
}
Canvas.java
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter,
@NonNull Paint paint) {
drawArc(oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle, useCenter,
paint);
}
startAngle 为开始的角度,sweepAngle为圆弧滑过的角度。代码如下:
RectF oval = new RectF(-mRadius, -mRadius, mRadius, mRadius);
mPaint.setStyle(Paint.Style.FILL);
path.addArc(oval, -90, 60);
5.看看效果
画出了一个,那么6个就很好画,为了方面观察效果,我把每个都整成了不同颜色,方便大家看。
咦,不对劲呀,和我预想的不一样。我们可以再看看UI做的效果图。抛开图形旋转角度的因素,可以观察到,图形是随着时间的变化,红色边线一直拉长而形成的。最大长度是R,最小长度是0,或者你设置任意初始值,还有一点要注意,在红线延伸的过程中,夹角始终是60度。
6.重新计算
依旧是正弦函数,余弦函数,算出点在红线上的位置。
float L1 = (float) Math.sqrt(Math.pow(mRadius, 2.0) -
Math.pow(Math.sin(Math.toRadians(60)) * a, 2.0));
float consL1 = L1 / mRadius;
float sinL1 = (float) Math.sin(Math.toRadians(60)) * a / mRadius;
float L = (float) (L1 + Math.sin(Math.toRadians(30)) * a);
float tagX = L * sinL;
float tagY = L * consL - mRadius;
7.大功告成
/**
- @authoer create by markfrain
- @github https://github.com/furuiCQ
- 高怀见物理 和气得天真
- 时间: 4/28/21
- 描述: ShootView
*/
public class ShootView extends View {
private static final int DEGREE_60 = 60;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final RectF mBounds = new RectF();
private int mRadius;
private int mCenterX;
private int mCenterY;
private ValueAnimator mPlayAnimator;
private float swipeAgenl = mRadius;//延伸的距离
private float mShootLineTotalRotateAngle;//旋转角度
private ValueAnimator mPreShootLineTotalRotateAnimator;
private float padding = 20;
private ValueAnimator paddingAnimator;
private float fix = 4;
private ValueAnimator fixAnimator;
private static final float SHOOT_LINE_ROTATE_END_RADIANS = (float) (Math.PI / 6.0);//旋转结束弧度
private static final float SHOOT_LINE_ROTATE_START_RADIANS = (float) (Math.PI / 2.0);//旋转开始弧度
private static final float SHOOT_LINE_ROTATE_START_DEGREE =
(float) Math.toDegrees(SHOOT_LINE_ROTATE_END_RADIANS);//旋转开始角度
private static final int PRE_SHOOT_LINE_TOTAL_ROTATE_DURATION = 1000;
public static final Property<ShootView, Float> SHOOT_LINE_TOTAL_ROTATE_DEGREE =
new Property<ShootView, Float>(Float.class, null) {
@Override
public Float get(ShootView object) {
return object.mShootLineTotalRotateAngle;
}
@Override
public void set(ShootView object, Float value) {
object.mShootLineTotalRotateAngle = value;
object.invalidate();
}
};
public ShootView(Context context) {
this(context, null);
}
public ShootView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ShootView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPaint.setColor(Color.parseColor(“#ffc6c6c6”));
paddingAnimator = ValueAnimator.ofFloat(20, 0);
paddingAnimator.setInterpolator(new LinearInterpolator());
paddingAnimator.setDuration(PRE_SHOOT_LINE_TOTAL_ROTATE_DURATION);
paddingAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
padding = (float) animation.getAnimatedValue();
invalidate();
}
});
fixAnimator = ValueAnimator.ofFloat(4, 0);
fixAnimator.setInterpolator(new LinearInterpolator());
fixAnimator.setDuration(1200);
fixAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
fix = (float) animation.getAnimatedValue();
invalidate();
}
});
mPreShootLineTotalRotateAnimator =
ValueAnimator.ofFloat(-(SHOOT_LINE_ROTATE_START_DEGREE / 2.0f) - 240.0f,
-(SHOOT_LINE_ROTATE_START_DEGREE / 2.0f) - 120.0f);
mPreShootLineTotalRotateAnimator.setInterpolator(new LinearInterpolator());
mPreShootLineTotalRotateAnimator.setDuration(PRE_SHOOT_LINE_TOTAL_ROTATE_DURATION);
mPreShootLineTotalRotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mShootLineTotalRotateAngle = (float) animation.getAnimatedValue();
invalidate();
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// drawTest(canvas);
drawArc(canvas);
drawCircle(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBounds.set(0 + getPaddingLeft(), 0 + getPaddingTop(), w - getPaddingRight(),
h - getPaddingBottom());
mRadius = (int) (Math.min(mBounds.width(), mBounds.height()) / 2);
mCenterX = (int) mBounds.centerX();
mCenterY = (int) mBounds.centerY();
swipeAgenl = mRadius * 2 / 3f;
}
float mStartX;
float mStartY;
int colors[] = {Color.RED, Color.GREEN, Color.YELLOW, Color.MAGENTA, Color.CYAN, Color.GRAY};
private void drawTest(Canvas canvas) {
drawCircle(canvas);
canvas.save();
canvas.translate(mCenterX, mCenterY);
int i = 0;
canvas.save();
canvas.rotate(-DEGREE_60 * i);
Path path = new Path();
float stopX = (float) Math.sqrt(3) * mRadius / 2f;
float stopY = -mRadius / 2f;
canvas.drawLine(0, -mRadius, stopX, stopY, mPaint);
mPaint.setColor(Color.RED);
canvas.drawPoint(stopX, stopY, mPaint);
mPaint.setColor(Color.RED);
//canvas.drawLine(0, 0, stopX, stopY, mPaint);
RectF oval = new RectF(-mRadius, -mRadius, mRadius, mRadius);
RectF rectF = new RectF(-mRadius, -2 * mRadius, mRadius, 0);
mPaint.setStyle(Paint.Style.FILL);
path.addArc(oval, -90, 60);
//计算直接点的
float tagX = (float) (Math.sin(Math.toRadians(60)) * mRadius / Math.cos(Math.toRadians(30 - swipeAgenl)) * Math.sin(Math.toRadians(60 - swipeAgenl)));
float tagY = (float) (Math.sin(Math.toRadians(60)) * mRadius / Math.cos(Math.toRadians(30 - swipeAgenl)) * Math.cos(Math.toRadians(60 - swipeAgenl))) - mRadius;
// float tagX = Math.sqrt(Math.pow(mRadius,2.0) - Math.pow(Math.sin(Math.toRadians(60) * swipeAgenl), 2.0));
// float L = (float) Math.sqrt(Math.pow(mRadius, 2.0) - Math.pow(Math.sin(Math.toRadians(60)) * swipeAgenl, 2.0));
// float consL = L / mRadius;
// float sinL = (float) Math.sin(Math.toRadians(60)) * swipeAgenl / mRadius;
// float LL = (float) (L + Math.sin(Math.toRadians(30)) * swipeAgenl);
//
// float tagX = LL * sinL;
// float tagY = LL * consL - mRadius;
canvas.drawPoint(tagX, tagY, mPaint);
// path.moveTo(stopX, stopY);
// path.lineTo(tagX, tagY);
// path.lineTo(0, -mRadius);
canvas.drawPath(path, mPaint);
// }
}
private void drawArc(Canvas canvas) {
canvas.save();
canvas.translate(mCenterX, mCenterY);
结尾
最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。
当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。
高级UI,自定义View
UI这块知识是现今使用者最多的。当年火爆一时的Android入门培训,学会这小块知识就能随便找到不错的工作了。
不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
理吧!
[外链图片转存中…(img-pVf3WRSU-1715236307266)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!