2024年安卓最全【BYM】Android 实现相机快门动画,2024年最新数据库索引高频面试题

写在最后

由于本文罗列的知识点是根据我自身总结出来的,并且由于本人水平有限,无法全部提及,欢迎大神们能补充~

将来我会对上面的知识点一个一个深入学习,也希望有童鞋跟我一起学习,一起进阶。

提升架构认知不是一蹴而就的,它离不开刻意学习和思考。

**这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家,**梳理了多年的架构经验,筹备近1个月最新录制的,相信这份视频能给你带来不一样的启发、收获。

最近还在整理并复习一些Android基础知识点,有问题希望大家够指出,谢谢。

希望读到这的您能转发分享和关注一下我,以后还会更新技术干货,谢谢您的支持!

转发+点赞+关注,第一时间获取最新知识点

Android架构师之路很漫长,一起共勉吧!

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

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

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

5.解题思路

a.找寻圆上的2个点

首先是6个等边三角形,逐步的往内圈圆心聚合,等边三角形的间距在缩小。那么这6个等边三角形只是所处的角度不一样,编写代码初期,我们可以先画一个,来实现一个等边三角形往圆心聚合的效果。 image.png

//可以得出我们的两个点(0,-R),(√3/2/R,R/2)
float startX = 0;
float startY = -mRadius;
float stopX = (float) Math.sqrt(3) * mRadius / 2f;
float stopY = -mRadius / 2f;

b.找寻第三个点TagPoint。

如果简单的实现的话,我们可以当做第三个点,就在蓝色的线上。此时只要求解,当第三个点与(0,-R)组成的边a,(0,-R)与(√3/2/R,R/2)点组成的边b的夹角Θ的值动态变化下,我们第三个点的位置就行了。也就是说夹角Θ是变量,从0到60度。

WX20210430-094133@2x.png

c.推导公式求解x和y。

辅助线我就不画了,我直接给出推导公式

image.png

转换成java代码如下

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;

运行看下效果是不是符合预期

wkxyz-u17vn.gif

4.圆弧

点(0,-R)到(√3/2/R,R/2)点与圆相交处会有个圆弧。这里利用Path.addArc或者canvas.drawArc方法都可以绘制。所传参方式有两种,其实本质都是传入一个矩形然后在矩形框内绘制一个圆弧。

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个就很好画,为了方面观察效果,我把每个都整成了不同颜色,方便大家看。

r729h-42qdy.gif

咦,不对劲呀,和我预想的不一样。我们可以再看看UI做的效果图。抛开图形旋转角度的因素,可以观察到,图形是随着时间的变化,红色边线一直拉长而形成的。最大长度是R,最小长度是0,或者你设置任意初始值,还有一点要注意,在红线延伸的过程中,夹角始终是60度。

WX20210430-101533@2x.png

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

总结

Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!

上面分享的字节跳动公司2021年的面试真题解析大全,笔者还把一线互联网企业主流面试技术要点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

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

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

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

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

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

处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

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

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

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

  • 13
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值