分享读者
作者2013年java转到Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。
被人面试过,也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!
我们整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。
主要包括腾讯,以及字节跳动,阿里,华为,小米,等一线互联网公司主流架构技术。
如果你觉得自己学习效率低,缺乏正确的指导,可以一起学习交流!
我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
- decoration:BoxDecoration()
- color: 背景色
- border: 边框样式, BoxBorder 类型, 常用
Border.all(width: 5)
来指定 - borderRadius: 边框圆角, BorderRadiusGeometry 类型, 常用
BorderRadius.circular(8)
来指定 - boxShadow:BoxShadow()
- color: 阴影颜色
- offset: 阴影偏移量
- spreadRadius: 延伸,在 offset 的基础上对 x,y 分别增加
class ContainerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
// width、height不指定,默认是包裹内容
width: 200,
height: 200,
child: Icon(Icons.pets, size: 50, color: Colors.white),
// 子元素所在位置
alignment: Alignment.topLeft,
padding: EdgeInsets.all(20),
margin: EdgeInsets.all(10),
// 旋转5度,缩小一半
transform: Matrix4.rotationZ(degree2Radia(5)).scaled(0.5),
color: Colors.red,
),
Container(
width: 200,
height: 200,
child: Icon(Icons.accessibility, size: 50, color: Colors.white),
// color与decoration冲突,两者只有选择其中一个
// color: Colors.red,
decoration: BoxDecoration(
color: Colors.red, // 背景色
border: Border.all(width: 5, color: Colors.blueAccent), // 边框
borderRadius: BorderRadius.circular(8), // 圆角
boxShadow: [
BoxShadow(
color: Colors.blueGrey, // 阴影颜色
offset: Offset(10, 10), // 阴影偏移量
spreadRadius: 5, // 延伸,相当于offset为 15,15
),
]),
)
],
);
}
double degree2Radia(double degree) {
return degree * pi / 180;
}
}
二、多子布局 Widget
多子布局, 顾名思义就是只能包含多个子控件的 widget
1、Flex
Flutter 中的 Flex
与 css 中的 flex 布局很类似, 可以很灵活的控制内部子 widget 的摆放, 不过一般情况下不会直接使用, 而是使用其子类 Row
/ Column
:
- Row/Column 继承自 Flex
- Row = Flex(direction: Axis.horizontal)
- mainAxis(主轴): 水平向右
- crossAxis(交叉轴): 竖直向下
- Column = Flex(direction: Axis.vertical)
- mainAxis(主轴): 竖直向下
- crossAxis(交叉轴): 水平向右
默认情况下, Row 在水平方向上会尽可能占据比较大的空间, 这是因为其 mainAxisSize
属性默认为 MainAxisSize.max
导致:
Column 与 Row 除了方向不同, 其它基本一致, 故掌握 Row 的情况后, Column 自然也会掌握
class ButtonRowDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
/// Row特点:
/// - 水平方向尽可能占据比较大的空间
/// * 如果水平方向希望包裹内容,可以设置 mainAxisSize = min
/// - 垂直方向包裹内容
return Column(
children: [
RaisedButton(
child: Row(
children: [Icon(Icons.bug_report), Text(“bug报告(MainAxisSize.max)”)],
),
onPressed: () {},
),
RaisedButton(
child: Row(
mainAxisSize: MainAxisSize.min, // 包裹内容。包裹是max占满父widget
children: [Icon(Icons.bug_report), Text(“bug报告(MainAxisSize.min)”)],
),
onPressed: () {},
),
],
);
}
}
2、Row
Row 比较重点的是主轴及交叉轴的对齐:
- MainAxisAlignment:
- start: 主轴的开始位置挨个摆放元素
- end: 主轴的结束位置挨个摆放元素
- center: 主轴的中心点对齐
- spaceBetween: 左右两边的间距为 0,其它元素之间平分间距
- spaceAround: 左右两边的间距是其它元素之间的间距的一半
- spaceEvenly: 所有的间距平分空间
- CrossAxisAlignment:
- start: 交叉轴的起始位置对齐
- end: 交叉轴的结束位置对齐
- center: 中心点对齐(默认值)
- baseline: 基线对齐(必须有文本的时候才起效果)
- 使用 baseline 对齐必须指定 textBaseline, 否则会报错.
- stretch: 先让 Row 占据交叉轴尽可能大的空间, 将所有子 widget 交叉轴的高度, 拉伸到最大
class RowDemo1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
itemRow(“start”, MainAxisAlignment.start, “center”, CrossAxisAlignment.center),
itemRow(“end”, MainAxisAlignment.end, “center”, CrossAxisAlignment.center),
itemRow(“center”, MainAxisAlignment.center, “center”, CrossAxisAlignment.center),
itemRow(“spaceBetween”, MainAxisAlignment.spaceBetween, “center”, CrossAxisAlignment.center),
itemRow(“spaceAround”, MainAxisAlignment.spaceAround, “center”, CrossAxisAlignment.center),
itemRow(“spaceEvenly”, MainAxisAlignment.spaceEvenly, “center”, CrossAxisAlignment.center),
],
);
}
Widget itemRow(
String mainAxisAlignmentStr,
MainAxisAlignment mainAxisAlignment,
String crossAxisAlignmentStr,
CrossAxisAlignment crossAxisAlignment) {
return Container(
height: 120,
margin: const EdgeInsets.only(bottom: 8.0),
color: Colors.pink[100],
child: Stack(
fit: StackFit.expand,
children: [
Row(
mainAxisAlignment: mainAxisAlignment,
crossAxisAlignment: crossAxisAlignment,
// textDirection: TextDirection.ltr, // rtl: 从右到左排版; ltr: 从左到右排版(默认)
children: [
Container(width: 80, height: 60, color: Colors.red),
Container(width: 120, height: 100, color: Colors.green),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
),
Positioned(
left: 0,
bottom: 0,
child: Text(
“GitLqr >>> main:
m
a
i
n
A
x
i
s
A
l
i
g
n
m
e
n
t
S
t
r
,
c
r
o
s
s
:
mainAxisAlignmentStr , cross:
mainAxisAlignmentStr,cross:crossAxisAlignmentStr”,
style: TextStyle(fontSize: 20, backgroundColor: Colors.black54, color: Colors.white),
),
)
],
),
);
}
}
class RowDemo2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 基线对齐
return Column(
children: [
itemRow(“spaceEvenly”, MainAxisAlignment.spaceEvenly, “start”, CrossAxisAlignment.start),
itemRow(“spaceEvenly”, MainAxisAlignment.spaceEvenly, “center”, CrossAxisAlignment.center),
itemRow(“spaceEvenly”, MainAxisAlignment.spaceEvenly, “end”, CrossAxisAlignment.end),
itemRow(“spaceEvenly”, MainAxisAlignment.spaceEvenly, “stretch”, CrossAxisAlignment.stretch),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.baseline,
// alphabetic 与 ideographic 这2种基线几乎没差
textBaseline: TextBaseline.ideographic,
children: [
Container(width: 80,height: 60, color: Colors.red, child: Text(“Hellxo”, style: TextStyle(fontSize: 20))),
Container(width: 120, height: 100, color: Colors.green, child: Text(“Woxrld”, style: TextStyle(fontSize: 30)),),
Container(width: 90, height: 80, color: Colors.blue, child: Text(“abxc”, style: TextStyle(fontSize: 12))),
Container(width: 50, height: 120, color: Colors.orange, child: Text(“cxba”, style: TextStyle(fontSize: 40))),
],
),
],
);
}
Widget itemRow(
String mainAxisAlignmentStr,
MainAxisAlignment mainAxisAlignment,
String crossAxisAlignmentStr,
CrossAxisAlignment crossAxisAlignment) {
return Container(
height: 140,
margin: const EdgeInsets.only(bottom: 8.0),
color: Colors.pink[100],
child: Stack(
fit: StackFit.expand,
children: [
Row(
mainAxisAlignment: mainAxisAlignment,
crossAxisAlignment: crossAxisAlignment,
// textDirection: TextDirection.ltr, // rtl: 从右到左排版; ltr: 从左到右排版(默认)
children: [
Container(width: 80, height: 60, color: Colors.red),
Container(width: 120, height: 100, color: Colors.green),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
),
Positioned(
left: 0,
bottom: 0,
child: Text(
“GitLqr >>> main:
m
a
i
n
A
x
i
s
A
l
i
g
n
m
e
n
t
S
t
r
,
c
r
o
s
s
:
mainAxisAlignmentStr , cross:
mainAxisAlignmentStr,cross:crossAxisAlignmentStr”,
style: TextStyle(fontSize: 20, backgroundColor: Colors.black54, color: Colors.white),
),
)
],
),
);
}
}
最后一组是
CrossAxisAlignment.baseline
的效果, 可以看到不管文字多大, 字母x
的底部都是在一条线上的, 这就是基线对齐.
值得注意的是, 使用CrossAxisAlignment.baseline
必须同时指定基线textBaseline(默认值为null)
, 其值TextBaseline.ideographic
与TextBaseline.alphabetic
几乎没差
3、Column
Column 与 Row 都是继承自 Flex, 两者除了在方向上有区别外, 其他特性几乎完全一样, 这里只补充一点它们排版方向上的不同之处:
- Row: 排版方向 TextDirection
- rtl: 从右到左排版
- ltr: 从左到右排版(默认)
- Column: 排版方向 VerticalDirection
- up: 从下到上排版
- down: 从上到下排版(默认)
class ColumnDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
verticalDirection: VerticalDirection.down,
// up: 从下到上排版; down: 从上到下排版(默认)
children: [
Container(width: 80, height: 60, color: Colors.red),
Container(width: 120, height: 100, color: Colors.green),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
Text(
“GitLqr >>> VerticalDirection.down”,
style: TextStyle(fontSize: 20, backgroundColor: Colors.black54, color: Colors.white),
),
],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
verticalDirection: VerticalDirection.up,
// up: 从下到上排版; down: 从上到下排版(默认)
children: [
Container(width: 80, height: 60, color: Colors.red),
Container(width: 120, height: 100, color: Colors.green),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
Text(
“GitLqr >>> VerticalDirection.up”,
style: TextStyle(fontSize: 20, backgroundColor: Colors.black54, color: Colors.white),
),
],
),
),
]);
}
}
4、Flexible(Expanded)
-
Flexible 中的属性:
-
fit: 填充模式
-
tight: 子控件强制填满可用空间
-
loose: 子控件只占用本身大小
-
flex: 当 fit 为 tight 时才会生效 (重点: width 比 = flex 比)
-
不指定 flex 时: 按等分的方式来拉伸 Flexible 直至填满可用空间, 相当于 flex 都是 1
-
有指定 flex 时: 按 flex 的比例来拉伸 Flexible 直至填满可用空间, 此时原本的 width 已经无效了
-
Expanded = Flexible(fit: FlexFit.tight)
-
当 Flex(Row/Column)还有可用空间时, 拉伸子控件大小
-
当子控件超出 Flex(Row/Column)空间时, 缩小子控件大小
class ExpandedDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
item1(),
tip(“Flexible fit: FlexFit.tight flex: 1”),
item2(),
tip(“Expanded flex: 1 , flex: 1 (width: 120)”),
item3(),
tip(“Expanded flex: 1 , flex: 2 (width: 10000)”),
],
);
}
Widget item1() {
return Row(
children: [
Flexible(
fit: FlexFit.tight,
flex: 1,
child: Container(width: 80, height: 60, color: Colors.red),
),
Flexible(
fit: FlexFit.tight,
flex: 1,
child: Container(width: 120, height: 100, color: Colors.green),
),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
);
}
Widget item2() {
return Row(
children: [
Expanded(
flex: 1,
child: Container(width: 80, height: 60, color: Colors.red),
),
Expanded(
flex: 1,
child: Container(width: 120, height: 100, color: Colors.green),
),
Container(width: 90, height: 80, color: Colors.blue),
Container(width: 50, height: 120, color: Colors.orange),
],
);
}
Widget item3() {
return Row(
最后
针对于上面的问题,我总结出了互联网公司Android程序员面试涉及到的绝大部分面试题及答案,并整理做成了文档,以及系统的进阶学习视频资料。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
文档,以及系统的进阶学习视频资料。
(包括Java在Android开发中应用、APP框架知识体系、高级UI、全方位性能调优,NDK开发,音视频技术,人工智能技术,跨平台技术等技术资料),希望能帮助到你面试前的复习,且找到一个好的工作,也节省大家在网上搜索资料的时间来学习。
[外链图片转存中…(img-NHxPoJl1-1715621637885)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!