• 点击按钮会移除Child

I/flutter (22218): parent build…
I/flutter (22218): child deactivate…
I/flutter (22218): child dispose…

  • 将MyApp的代码由 child:isShowChild?Child():Text(“演示移除Child”),改为
    child:Child(),点击按钮时

I/flutter (22765): parent build…
I/flutter (22765): child didUpdateWidget…
I/flutter (22765): child build…

基础widget

文本显示

Text

Text是展示单一格式的文本Widget(Android TextView)。

import ‘package:flutter/material.dart’;
/// main方法 调用runApp传递Widget,这个Widget成为widget树的根
void main() => runApp(TextApp());
/// 1、单一文本Text
//创建一个无状态的Widget
class TextApp extends
StatelessWidget {

@override
Widget build(BuildContext context) {
//封装了应用程序实现Material Design所需要的一些widget
return MaterialApp(
title: “Text演示”,
//标题,显示在recent时候的标题
//主页面
//Scaffold : Material Design布局结构的基本实现。
home: Scaffold(
//ToolBar/ActionBar
appBar: AppBar(title: Text(“Text”)),
body: Text(“Hello,Flutter”
),
),
);
}
}

在使用 Text显示文字时候,可能需要对文字设置各种不同的样式,类似Android的 android:textColor/Size等

在Flutter中也拥有类似的属性

Widget _TextBody() {
return Text(
“Hello,Flutter”,
style: TextStyle(
//颜色
color: Colors.red,
//字号 默认14
fontSize: 18,
//粗细
fontWeight: FontWeight.w800,
//斜体
fontStyle: FontStyle.italic,
//underline:下划线,overline:上划线,lineThrough:删除线
decoration: TextDecoration.lineThrough,
decorationColor: Colors.black,
//solid:实线,double:双线,dotted:点虚线,dashed:横虚线,wavy:波浪线
decorationStyle:
TextDecorationStyle.wavy),
);
}
class TextApp extends StatelessWidget {

@override
Widget
build(BuildContext context)
{
return MaterialApp(
title: “Text演示”,
home: Scaffold(
appBar: AppBar(title: Text(“Text”)),
body: _TextBody(),
),
);
}
}

在这里插入图片描述
RichText

如果需要显示更为丰富样式的文本(比如一段文本中文字不同颜色),可以使用 RichText或者 Text.rich

Widget _RichTextBody() {
var textSpan = TextSpan(
text: “Hello”,
style: TextStyle(color: Colors.red),
children: [
TextSpan(text: “Flu”, style: TextStyle(color: Colors.blue)),
TextSpan(text: “uter”, style: TextStyle(color: Colors.yellow)),
],
);
//Text.rich(textSpan);
return RichText(text: textSpan);
}

在这里插入图片描述
DefaultTextStyle
在widget树中,文本的样式默认是可以被继承的,因此,如果在widget树的某一个节点处设置一个默认的文本样式,那么该节点的子树中所有文本都会默认使用这个样式。相当于在Android中定义 Theme

Widget _DefaultStyle(){
DefaultTextStyle(
//设置文本默认样式
style: TextStyle(
color:Colors.red,
fontSize: 20.0,
),
textAlign: TextAlign.start,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(“Hello Flutter!”),
Text(“Hello Flutter!”),
Text(“Hello Flutter!”,
style: TextStyle(
inherit: false,
//不继承默认样式
color: Colors.grey
),
),
],
),
);
}

FlutterLogo
这个Widget用于显示Flutter的logo…

Widget flutterLogo() {
return FlutterLogo(
//大小
size: 100,
//logo颜色 默认为 Colors.blue
colors: Colors.red,
//markOnly:只显示logo,horizontal:logo右边显示flutter文字,stacked:logo下面显示文字
style: FlutterLogoStyle.stacked,
//logo上文字颜色
textColor: Colors.blue,
);
}

在这里插入图片描述
Icon

主要用于显示内置图标的 Widget

Widget icon() {
return Icon(
//使用预定义Material icons
// https://docs.flutter.io/flutter/material/Icons-class.html

Icons.add,
size: 100,
color: Colors.red);
}

在这里插入图片描述
Image
显示图片的 Widget。图片常用的格式主要有bmp,jpg,png,gif,webp等,Android中并不是天生支持gif和webp动图,但是这一特性在flutter中被很好的支持了。

在这里插入图片描述
Iamge.asset
在工程目录下创建目录,如:assets,将图片放入此目录。打开项目根目录:pubspec.yaml
在这里插入图片描述

return MaterialApp(
title: “Image演示”,
home: Scaffold(
appBar: AppBar(title: Text(“Image”)),
body: Image.asset(“assets/banner.jpeg”),
),
);

Image.file
在sd卡中放入一张图片。然后利用path_provider库获取sd卡根目录(Dart库版本可以在:https://pub.dartlang.org/packages查询)。
在这里插入图片描述
注意权限

class ImageState extends State {
Image image;

@override
void initState() {
super.initState();
getExternalStorageDirectory().then((path) {
setState(() {
image = Image.file(File(“ p a t h . p a t h {path.path} path.path{Platform.pathSeparator}banner.jpeg”
));
});
});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
title: “Image演示”,
home: Scaffold(
appBar: AppBar(title: Text(“Image”)),
body: image,
),
);
}
}

Image.network

直接给网络地址即可。
Flutter 1.0,加载https时候经常出现证书错误。必须断开AS打开app

Image.memory

Future<List> _imageByte() async {
String path = (await getExternalStorageDirectory()).path;
return await File(“ p a t h path path{Platform.pathSeparator}banner.jpeg”).readAsBytes();
}
class ImageState extends State {
Image image;

@override
void initState() {
super.initState();
_imageByte().then((bytes) {
setState(() {
image = Image.memory(bytes);
});
});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
title: “Image演示”,
home: Scaffold(
appBar: AppBar(title: Text(“Image”)),
body: image,
),
);
}
}

CircleAvatar

CircleAvatar(
//图片提供者 ImageProvider
backgroundImage: AssetImage(“assets/banner.jpeg”),
//半径,控制大小
radius: 50.0,
);

FadeInImage
当使用默认 Image widget显示图片时,您可能会注意到它们在加载完成后会直接显示到屏幕上。这可能会让用户产生视觉突兀。如果最初显示一个占位符,然后在图像加载完显示时淡入,我们可以使用 FadeInImage来达到这个目的!

image = FadeInImage.memoryNetwork(
placeholder: kTransparentImage,
image: ‘https://flutter.io/images/homepage/header-illustration.png’,
);

按钮

Material widget库中提供了多种按钮Widget如RaisedButton、FlatButton、OutlineButton等,它们都是直接或间接对RawMaterialButton的包装定制,所以他们大多数属性都和 RawMaterialButton一样。所有Material 库中的按钮都有如下相同点:

  1. 按下时都会有“水波动画”。
  2. 有一个onPressed属性来设置点击回调,当按钮按下时会执行该回调,如果不提供该回调则按钮会处于禁用状态,禁用状态不响应用户点击。

RaisedButton
"漂浮"按钮,它默认带有阴影和灰色背景

RaisedButton(
child: Text(“normal”),
onPressed: () => {},
)

FlatButton

扁平按钮,默认背景透明并不带阴影

FlatButton(
child: Text(“normal”),
onPressed: () => {},
)

OutlineButton

默认有一个边框,不带阴影且背景透明。

OutlineButton(
child: Text(“normal”),
onPressed: () => {},
)

IconButton

可点击的Icon

IconButton(
child: Text(“normal”),
onPressed: () => {},
)

按钮外观可以通过其属性来定义,不同按钮属性大同小异

const FlatButton({

@required this.onPressed,
//按钮点击回调
this.textColor,
//按钮文字颜色
this.disabledTextColor,
//按钮禁用时的文字颜色
this.color,
//按钮背景颜色
this.disabledColor,
//按钮禁用时的背景颜色
this.highlightColor,
//按钮按下时的背景颜色
this.splashColor,
//点击时,水波动画中水波的颜色
this.colorBrightness,
//按钮主题,默认是浅色主题
this.padding,
//按钮的填充
this.shape,
//外形
@required this.child,
//按钮的内容
})
FlatButton( onPressed: () => {},
child: Text(“Raised”),
//蓝色
color: Colors.blue,
//水波
splashColor: Colors.yellow,
//深色主题,这样文字颜色会变成白色
colorBrightness: Brightness.dark,
//圆角按钮
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50)
),
)

而 RaisedButton,默认配置有阴影,因此在配置 RaisedButton 时,拥有一系列 elevation 属性的配置

const RaisedButton({

this.elevation = 2.0,
//正常状态下的阴影
this.highlightElevation = 8.0,
//按下时的阴影
this.disabledElevation = 0.0,
// 禁用时的阴影

}

输入框

import ‘package:flutter/material.dart’;
void main() => runApp(Demo1());
class Demo1 extends StatelessWidget {

@override
Widget build(BuildContext context) {
return MaterialApp(
title: “Demo1”,
home: Scaffold(
appBar: AppBar(
title: Text(“登录”),
),
//线性布局,垂直方向
body: Column(
children: [
TextField(
//自动获得焦点
autofocus: true,
decoration: InputDecoration(
labelText: “用户名”,
hintText: “用户名或邮箱”,
prefixIcon: Icon(Icons.person)),
),
TextField(
//隐藏正在编辑的文本
obscureText: true,
decoration: InputDecoration(
labelText: “密码”,
hintText: “您的登录密码”,
prefixIcon: Icon(Icons.lock)),
),
],
),
),
);
}
}

在这里插入图片描述
这个效果非常的“系统”,我们可能大多数情况下需要将下划线更换为矩形边框,这时候可能就需要组合widget来完成:

//容器 设置一个控件的尺寸、背景、margin
Container(
margin: EdgeInsets.all(32),
child: TextField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: “用户名”,
hintText: “用户名或邮箱”,
prefixIcon: Icon(Icons.person),
border: InputBorder.none
//隐藏下划线
)),
//装饰
decoration: BoxDecoration(
// 边框浅灰色,宽度1像素
border: Border.all(color: Colors.red[200], width: 1.0),
//圆角
borderRadius: BorderRadius.circular(5.0),
),
)

在这里插入图片描述
焦点控制

FocusNode: 与Widget绑定,代表了这个Widget的焦点

FocusScope: 焦点控制范围

FocusScopeNode:控制焦点

class _TextFocusState extends State {
FocusNode focusNode1 = new
FocusNode(); FocusNode focusNode2 = new FocusNode();
void _listener() {
debugPrint(“用户名输入框焦点:${focusNode1.hasFocus}”);
}

@override
void initState() {
super.initState();
//监听焦点状态改变事件
focusNode1.addListener(_listener);
}

@override
void dispose() {
super.dispose();
focusNode1.dispose();
focusNode2.dispose();
}

@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
autofocus: true,
//关联焦点
focusNode: focusNode1,
//设置键盘动作为: 下一步
textInputAction: TextInputAction.next,
//点击下一步执行回调
onEditingComplete: () {
//获得 context对应UI树的焦点范围 的焦点控制器
FocusScopeNode focusScopeNode = FocusScope.of(context);
//将焦点交给focusNode2
focusScopeNode.requestFocus(focusNode2);
},
decoration: InputDecoration(
labelText: “用户名”,
hintText: “用户名或邮箱”,
prefixIcon: Icon(Icons.person)),
),
TextField(
//隐藏正在编辑的文本
obscureText: true,
focusNode: focusNode2,
decoration: InputDecoration(
labelText: “密码”,
hintText: “您的登录密码”,
refixIcon: Icon(Icons.lock)),
),
custom(),
],
);
}
}

获取输入内容

获取输入内容有两种方式:

  1. 定义两个变量,用于保存用户名和密码,然后在onChange触发时,各自保存一下输入内容。
  2. 通过controller直接获取。
    onChange获得输入内容:

TextField(
onChanged: (s) => debugPrint(“ssss:$s”),

controller获取:

定义一个controller:

//定义一个controller
TextEditingController _unameController=new TextEditingController();

然后设置输入框controller:

TextField(
controller: _unameController,
//设置controller

)

通过controller获取输入框内容

debugPrint(_unameController.text)

TextFormField

TextFormField比 TextField多了一些属性,其中 validator用于设置验证回调。在单独使用时与 TextField没有太大的区别。当结合 From,利用 From可以对输入框进行分组,然后进行一些统一操作(验证)

class _TextFocusState extends State {
//全局key

文末

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

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

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

学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

[外链图片转存中…(img-mSEBmRwc-1714705884811)]

【算法合集】

[外链图片转存中…(img-RtzCz5Bz-1714705884812)]

【延伸Android必备知识点】

[外链图片转存中…(img-fLaxr7w5-1714705884813)]

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

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

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐