WidgetSpan
: 用于构建内嵌 Widget 的 Span (比如:Icon)
/// Text.rich()的使用Demo
class TextRichDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text.rich(
TextSpan(
// text: “Hello lqr”,
// style: TextStyle(color: Colors.red,fontSize: 20),
children: [
TextSpan(text: “Hello World”, style: TextStyle(color: Colors.red)),
TextSpan(
text: “Hello Flutter”, style: TextStyle(color: Colors.green)),
WidgetSpan(child: Icon(Icons.favorite, color: Colors.red)),
TextSpan(text: “Hello Dart”, style: TextStyle(color: Colors.blue)),
],
),
style: TextStyle(fontSize: 26),
);
}
}
二、按钮 Widget
1、常见 Button
- RaisedButton : 突出的 Button(从 v1.25.0 过时,推荐使用 ElevatedButton)
- FlatButton : 扁平的 Button(从 v1.25.0 过时,推荐使用 TextButton)
- OutlineButton : 边框 Button(从 v1.25.0 过时,推荐使用 OutlinedButton)
- FloatingActionButton : 浮动按钮,简称 FAB,一般用在 Scaffold 中
- floatingActionButtonLocation : 可指定 FAB 在界面中的位置,比如底部居中:
FloatingActionButtonLocation.centerFloat
在使用这些常见 Widget 时,经常会看到构造方法中有两类
"必传"参数
:
- 必传参数 : 指的是 Dart 语法中方法的必传参数,这种参数不传一定报错(编译不通过)。
required
参数 : 使用 @required(或 required 关键字)修饰的可选参数
,这种不传编译可以通过,但是会报警告。
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(“基础Widget”)),
body: HomeContent(),
// 4. FloatingActionButton
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () => print(“FloatingActionButton Click”),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
…
class ButtonDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
// 1. 突出的Button(从 v1.25.0 过时,推荐使用 ElevatedButton)
RaisedButton(
child: Text(“RaisedButton”),
textColor: Colors.red, // 文字颜色(也可以在Text的style中设置)
color: Colors.blue, // 按钮背景色
onPressed: () => print(“RaisedButton Click”),
),
// 2. 扁平的Button(从 v1.25.0 过时,推荐使用 TextButton)
FlatButton(
child: Text(“FlatButton”),
color: Colors.orange,
onPressed: () => print(“FlatButton Click”),
),
// 3. 边框Button(从 v1.25.0 过时,推荐使用 OutlinedButton)
OutlineButton(
child: Text(“OutlineButton”),
onPressed: () => print(“OutlineButton Click”)),
// 4. FloatingActionButton,一般用在Scaffold中
// FloatingActionButton(onPressed: onPressed)
// 5. 自定义Button:图标-文字-背景-圆角
FlatButton(
color: Colors.amberAccent,
shape: RoundedRectangleBorder( // 圆角
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: MainAxisSize.min, // 默认是max,占满父Widget;min是包裹内容
children: [
Icon(Icons.favorite, color: Colors.red), // 图标
Text(“喜欢作者”), // 文字
],
),
onPressed: () => print(“自定义Button”), // onPressed必传,否则样式可能会出问题
)
],
);
}
}
2、定制 Button
- 默认间隔 : 默认情况下 Button 上下有一定有间隔,可以指定 materialTapTargetSize 来修改
MaterialTapTargetSize.padded
:(默认值) 当按钮宽(或高)不足 48px 时,就把宽(或高)扩展到 48pxMaterialTapTargetSize.shrinkWrap
:紧缩包裹,可以去除上下的间隔- 最小宽度 :
ButtonTheme
(也是个 Widget,包裹 Button) 或minWidth
(Button 的一个属性) - 内间距 : 修改
padding
属性值
class ButtonExtensionDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
/// 1. 默认情况下Button上下有一定有间隔
/// MaterialTapTargetSize.padded:当按钮宽(或高)不足48px时,就把宽(或高)扩展到48px。
/// MaterialTapTargetSize.shrinkWrap:紧缩包裹,可以去除上下的间隔。
FlatButton(
color: Colors.red,
child: Text(“Flat Button1”),
textColor: Colors.white,
onPressed: () {},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
FlatButton(
color: Colors.red,
child: Text(“Flat Button2”),
textColor: Colors.white,
onPressed: () {},
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
/// 2. 修改按钮的最小宽度:ButtonTheme
FlatButton(
minWidth: 30,
height: 30,
color: Colors.red,
child: Text(“”),
onPressed: () {},
),
ButtonTheme(
minWidth: 30,
height: 30,
child: FlatButton(
color: Colors.red,
child: Text(“”),
onPressed: () {},
),
),
/// 3. 修改按钮的内间距
FlatButton(
padding: EdgeInsets.all(0),
// 只能去除左右内间距,上下内间距可以指定一个固定height解决
color: Colors.red,
child: Text(“Float Button3”),
textColor: Colors.white,
onPressed: () {},
),
],
);
}
}
三、图片 Widget
Image
控件需要一个必传参数 ImageProvider image
,常见子类如下:
- NetworkImage : 用于加载网络图片
- 简单写法 :
Image.network('http://lqr.com/FSA_QR.png')
- AssetImage : 用于加载 app 包内图片
- 简单写法 :
Image.asset('assets/images/FSA_QR.png')
1、NetworkImage
- 常见属性:
- fit : 图片填充方式
- BoxFit.fill : 拉伸
- BoxFit.contain : 内容缩放至最长的一边贴边
- BoxFit.cover : 内容缩放至最短的一边贴边
- BoxFit.fitWidth : 宽度一定,高度自适应
- BoxFit.fitHeight : 高度一定,宽度自适应
- alignment :
- Alignment.bottomCenter : 底部居中
- Alignment.center : 居中
- Alignment(x, y) : 左上角是(-1, -1),右下角是(1, 1)
- color : color 不是背景色,而是用于图像混入的颜色,配合
colorBlendMode
使用 - repeat : 重复模式,比如纵向重复
ImageRepeat.repeatY
class ImageDemo01 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisSpacing: 8,
mainAxisSpacing: 8,
crossAxisCount: 3,
children: [
wrapItem(
Image(image: NetworkImage(imageUrl)),
“NetworkImage”,
),
wrapItem(
Image.network(imageUrl),
“Image.network()”,
),
Container(),
wrapItem(
Image.network(imageUrl, fit: BoxFit.fill), // 拉伸
“BoxFit.fill”,
),
wrapItem(
Image.network(imageUrl, fit: BoxFit.contain), // 内容缩放至最长的一边贴边
“BoxFit.contain”,
),
wrapItem(
Image.network(imageUrl, fit: BoxFit.cover), // 内容缩放至最短的一边贴边
“BoxFit.cover”,
),
wrapItem(
Image.network(imageUrl, fit: BoxFit.fitWidth), // 宽度一定,高度自适应
“BoxFit.fitWidth”,
),
wrapItem(
Image.network(imageUrl, fit: BoxFit.fitHeight), //高度一定,宽度自适应
“BoxFit.fitHeight”,
),
Container(),
wrapItem(
Image.network(imageUrl, alignment: Alignment.bottomCenter),
“Alignment.topLeft”,
),
wrapItem(
Image.network(imageUrl, alignment: Alignment.center),
“Alignment.center”,
),
wrapItem(
// 左上角是(-1, -1),右下角是(1, 1)
Image.network(imageUrl, alignment: Alignment(0, -1)),
“Alignment(0, -1)”,
),
wrapItem(
// color不是背景色,而是用于图像混入的颜色,配合 colorBlendMode 使用
Image.network(imageUrl,
color: Colors.green, colorBlendMode: BlendMode.colorDodge),
“BlendMode.colorDodge”,
),
wrapItem(
Image.network(imageUrl, repeat: ImageRepeat.repeatY),
“ImageRepeat.repeatY”,
),
],
);
}
Widget wrapItem(Widget widget, String tip) {
Text genTip(String tip) {
return Text(
tip,
style: TextStyle(
fontSize: 14,
color: Colors.white,
backgroundColor: Colors.black,
),
);
}
return Stack(
fit: StackFit.expand,
children: [
Container(color: Colors.red[100], child: widget),
Positioned(left: 4, bottom: 4, child: genTip(tip)),
],
);
}
}
2、AssetImage
使用 AssetImage
加载包内图片步骤如下:
- 在 Flutter 项目中创建一个文件夹目录(比如
assets/image
),存储图片 - 在
pubspec.yaml
进行配置
assets:
- assets/images/FSA_QR.png # 配置单张图片
- assets/images/ # 配置多张图片
- 使用图片
class ImageDemo02 extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 简单写法
// Image.asset(‘assets/images/FSA_QR.png’);
return Image(
image: AssetImage(‘assets/images/FSA_QR.png’),
);
}
}
3、占位图(placeHolder)
在网络图片未加载出来之前显示的图片称为占位图,可以使用 FadeInImage
实现占位图功能:
class ImageExtensionDemo extends StatelessWidget {
final imageUrl =
“https://up.enterdesk.com/edpic_source/ab/a0/40/aba040ce2daa32fa9cb0cc624b385c0a.jpg”;
@override
Widget build(BuildContext context) {
return FadeInImage(
fadeInDuration: Duration(milliseconds: 1),
fadeOutDuration: Duration(milliseconds: 1),
placeholder: AssetImage(“assets/images/FSA_QR.png”),
image: NetworkImage(imageUrl),
);
}
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
要如何成为Android架构师?
搭建自己的知识框架,全面提升自己的技术体系,并且往底层源码方向深入钻研。
大多数技术人喜欢用思维脑图来构建自己的知识体系,一目了然。这里给大家分享一份大厂主流的Android架构师技术体系,可以用来搭建自己的知识框架,或者查漏补缺;
对应这份技术大纲,我也整理了一套Android高级架构师完整系列的视频教程,主要针对3-5年Android开发经验以上,需要往高级架构师层次学习提升的同学,希望能帮你突破瓶颈,跳槽进大厂;
最后我必须强调几点:
1.搭建知识框架可不是说你整理好要学习的知识顺序,然后看一遍理解了能复制粘贴就够了,大多都是需要你自己读懂源码和原理,能自己手写出来的。
2.学习的时候你一定要多看多练几遍,把知识才吃透,还要记笔记,这些很重要! 最后你达到什么水平取决你消化了多少知识
3.最终你的知识框架应该是一个完善的,兼顾广度和深度的技术体系。然后经过多次项目实战积累经验,你才能达到高级架构师的层次。
你只需要按照在这个大的框架去填充自己,年薪40W一定不是终点,技术无止境
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
,需要往高级架构师层次学习提升的同学,希望能帮你突破瓶颈,跳槽进大厂;
最后我必须强调几点:
1.搭建知识框架可不是说你整理好要学习的知识顺序,然后看一遍理解了能复制粘贴就够了,大多都是需要你自己读懂源码和原理,能自己手写出来的。
2.学习的时候你一定要多看多练几遍,把知识才吃透,还要记笔记,这些很重要! 最后你达到什么水平取决你消化了多少知识
3.最终你的知识框架应该是一个完善的,兼顾广度和深度的技术体系。然后经过多次项目实战积累经验,你才能达到高级架构师的层次。
你只需要按照在这个大的框架去填充自己,年薪40W一定不是终点,技术无止境