总结
【Android 详细知识点思维脑图(技能树)】
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
}
2.子布局如何旋转?自动旋转?支持手势滑动旋转?快速滑动抬手继续旋转?
子布局如何旋转
所谓的旋转就是所有的子布局绕着圆形移动,布局一旦移动就代表中间位置改变,根据上面我们计算的子布局位置的公式来看:
中心点坐标
x=width/2+sin(a)*R
y=height/2+cos(a)*R
因为width
和R
都是已知并且定下来的尺寸,所以说,想要改变中心点坐标,只需修改 角度a就可以了。要想达到旋转效果的话就是让所有的子布局都同时移动相同的角度即可。
子布局原始角度值:
double angle = startAngle + averageAngle * i;
我们可以在此基础上加上一个可变的角度值,通过改变这个值,所有的子布局都会同时加上此值同时移动了位置。如下:
double angle = startAngle + averageAngle * i + rotateAngle;
其中 rotateAngle 就是可变的值。改变这个值就能让布局动起来
自动旋转
同理,我们只要搞个定时器,周期性修改这个rotateAngle
值,并setState(() {})
刷新下,看起来就自动旋转了。
支持手势滑动旋转
大家已经知道通过修改rotateAngle
值去实现旋转,那么支持手势滑动旋转顾名思义就是通过手势修改这个rotateAngle值就OK,那么手势处理Flutter提供了GestureDetector
组件,这个组件功能很强大,这里面我们使用了他的几个回调方法。
本次实现直接使用水平滑动监听,大家如果想兼容竖直滑动可以自己尝试修改就可以。
GestureDetector(
///水平滑动按下
onHorizontalDragDown: (DragDownDetails details) {…},
///水平滑动开始
onHorizontalDragStart: (DragStartDetails details) {
//记录拖动开始时当前的选择角度值
downAngle = rotateAngle;
//记录拖动开始时的x坐标
downX = details.globalPosition.dx;
},
///水平滑动中
onHorizontalDragUpdate: (DragUpdateDetails details) {
//滑动中X坐标值
var updateX = details.globalPosition.dx;
//计算当前旋转角度值并刷新
rotateAngle = (downX - updateX) * slipRatio + downAngle;
if (mounted) setState(() {});
},
///水平滑动结束
onHorizontalDragEnd: (DragEndDetails details) {…},
///滑动取消
onHorizontalDragCancel: () {…},
behavior: HitTestBehavior.opaque,//deferToChild translucent
child: xxx,
);
快速滑动抬手继续旋转
抬手还能继续旋转,也就是当我们快速滑动抬手的时候只要继续修改旋转角度值rotateAngle
就可以达到继续旋转的效果。当我们抬手的时候我们可以拿到什么呢?
例如:当我们骑着小黄单车在大路上快速的蹬着脚蹬子然后停止蹬,你的小黄已当时的速度飞驰在这个大路上,由于地面的摩擦力的影响,速度会越来越小,最后停止。
///水平滑动结束
onHorizontalDragEnd: (DragEndDetails details) {
//x方向上每秒速度的像素数
velocityX = details.velocity.pixelsPerSecond.dx;
_controller.reset();
_controller.forward();
},
//动画设置rotateAngle
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 1000),
);
animation = CurvedAnimation(
parent: _controller,
curve: Curves.linearToEaseOut,
);
animation = new Tween(begin: 1, end: 0).animate(animation)
…addListener(() {
//当前速度
var velocity = animation.value * -velocityX;
var offsetX = radius != 0 ? velocity * 5 / (2 * pi * radius) : velocity;
rotateAngle += offsetX;
setState(() => {});
})
…addStatusListener((status) {
if (status == AnimationStatus.completed) {
rotateAngle = rotateAngle % 360;
_startRotateTimer();
}
});
3.支持X轴旋转
上图是X轴方向查看旋转切面图,按照x轴旋转所有的x坐标都是相同的,y值从上往下不断增加。因为绕着X轴旋转时,X坐标是不变的,Y坐标值改变,当旋转了a角度时,现在的Y坐标如图所示为
Y坐标旋转后=height/2+y*cos(a) y值我们已经在上面计算过了,y=cos(a)*R
所以最终的计算公式是:
Y坐标值=height/2+cos(a)Rcos(a)
cos(a)在a=[0,90]区间时对应的值是1-0 即是 a=0度时cos(a)=1,就是原始状态(与Y轴平行),a=90度时cos(a)=0,就是与Y轴垂直准状态。所以我们可以设置a在0-90之间即可。
4.支持前后缩放子布局(起始角度为前,相对位置为后,最前面最大,反而越小)
上图为cos余弦曲线图。0
度和360
度最大 ,180
度最小,刚好与我们设计的初始值从0开始,然后逆时针绕一圈角度从0-360
度。
所以缩放比scale计算公式可以写为:
var scale = (1 - minScale) / 2 * (1 + cos(radian(angle - startAngle))) + minScale;
minScale
为最小缩放比,为了让缩放有个极限值,即 scale范围为:(minScale,1)
5.多个布局叠加时前面遮挡后面
从视觉感受,靠近前面的布局应该遮挡后面的布局,在Android当中bringToFront()
方法可以让布局置于前面,Flutter没有提供此方法,我们该如何处理这种情况呢?
Flutter提供一个Stack布局,也叫层叠式布局,当我们添加子布局到Stack布局中时,后面添加的会遮住前面添加的,所以只要我们在添加子布局的时候按照由后到前来添加即可。话说怎么知道是前是后呢?
知道实现思路现在要解决的问题是:
如何区分前与后?有什么条件可以区分?
1、根据坐标值?Y坐标小就是后面,Y坐标大就是前面?
答案是不一定;因为当我启动角度不是0的时候,比如是90度,那么最右面是前面,最左边是后面,这个时候是X坐标的大小区分前后关系,所以说单独使用坐标值的大小来决定前后关系是不对的。
2、根据前大后小原则?根据缩放值排序来添加子布局?
答案是可行;因为我们已经实现了前面的布局缩放值是1,后面的缩放值越来越小,而且我们已经处理了启动角度问题,所以根据缩放值来实现是可行的。
///通过缩放值进行排序,从小到大
childPointList.sort((a, b) {
return a.scale.compareTo(b.scale);
});
///遍历添加子布局
Stack(
children: childPointList.map(
(Point point) {
return Positioned(
width: point.width,
left: point.left,
top: point.top,
child: this.widget.children[point.index]);
},
).toList(),
),
通过上面方式即可实现前后遮挡效果了。
小知识点
Flutter 之Stack
组件Stack
一个可以叠加子控件的布局,这里主要讲一下 Positioned
,其他使用方式可以看下官网说明。
最后
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
- 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
- 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!