Flutter 面经

StatelessWidget和StatefulWidget

在Flutter中,widget分为两类:Stateful(有状态)和 stateless(无状态)widget。

stateless widget 没有内部状态,Icon、IconButton, 和Text都是无状态widget, 它们都是 StatelessWidget的子类。

stateful widget 是动态的,用户可以和其交互(例如输入一个表单、 或者移动一个slider滑块),或者可以随时间改变 (也许是数据改变导致的UI更新)。Checkbox, Radio, Slider, InkWell, Form, and TextField 都是 stateful widgets, 它们都是 StatefulWidget的子类。

StatelessWidget
Stateless widgets 是不可变的, 这意味着它们的属性不能改变——所有的值都是最终的。

如果无状态Widget里面有子Widget,并且子Widget是有状态的,则子Widget的内容是可以通过setState来更改的。无状态Widget影响的仅仅是自己是无状态的,不回影响他的父Widget和子Widget。

StatefulWidget
Stateful widgets 持有的状态可能在widget生命周期中发生变化。

创建一个有状态的widget需要进行以下操作:

要创建一个自定义有状态widget,需创建两个类:StatefulWidget和State。
我们要定义一个widget类,继承自StatefulWidget。
子State,包含该widget状态并定义该widget build()方法的类,它继承自State。
状态对象包含widget的状态和build() 方法。
当widget的状态改变时,状态对象调用setState(),告诉框架重绘widget

class TextPage extends StatefulWidget{
  @override
  TextPageState createState() => new TextPageState();
}

class TextPageState extends State<TextPage>{
	@override
  	Widget build(BuildContext context)
}

详细

Navigator路由

有显示跳转

Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage()));

还有隐式跳转
这种跳转需要先定义,后使用

Navigator.push 用来执行 Route 的入栈操作,就可以通过指定的 Route 跳转到对应的页面了
Navigator.pop 用来执行 Route 的退栈操作,即页面回退,可以添加可选参数 result 作为页面返回时携带的参数

context跨组件获取数据的一个封装

Flutter 中的生命周期

  • initState()
    表示当前 State 将和一个 BuildContext 产生关联,但是此时BuildContext 没有完全装载完成,如果你需要在该方法中获取 BuildContext ,可以 new Future.delayed(const Duration(seconds: 0, (){//context}); 一下。

  • didChangeDependencies()
    didChangeDependencies() 在 initState() 之后调用,当 State 对象的依赖关系发生变化时,该方法被调用,初始化时也会调用。

  • deactivate()
    deactivate() 当 State 被暂时从视图树中移除时,会调用这个方法,同时页面切换时,也会调用。

  • dispose()
    dispose() Widget 销毁了,在调用这个方法之前,总会先调用 deactivate()。

Scaffold

一个完整的页面可能会包含导航栏、抽屉菜单以及底部导航等等。如果每个路由页面都需要开发者自己手动去实现这些组件,这将会是很差的体验。在 Material 组件库中,提供了 Scaffold 组件用于搭建一个页面的骨架,让我们很容易的拼装出一个完整的页面。

  • AppBar 设置导航栏标题、导航栏菜单、导航栏底部的 Tab
  • TabBar 组件用于快速生成 Tab 菜单。在导航栏的底部通常是一组 Tab 菜单,可以通过上面 AppBar 的 bottom 属性来指定这组菜单
  • TabBarView
    通过上面的 TabBar 只能生成一个静态的菜单,Tab 菜单和 Tab 页面切换需要同步,然而实现这一功能的就需要通过 TabBarView 组件了。TabBarView 组件不仅可以轻松实现 Tab ,而且可以非常容易配合 TabBar 来实现同步切换和滑动状态同步
  • 抽屉菜单 drawer 、endDrawer 两个属性用于表示一个页面的左、右抽屉菜单。
  • 底部 Tab 导航栏 提供了 bottomNavigationBar 属性来指定底部导航,Material 组件库提供了 BottomNavigationBar 和 BottomNavigationBarItem 来实现底部导航。
  • 详细

Row和Column

Row和Column是flutter中最基础的容器组件,Row用来水平放置子组件,Column用来垂直放置子组件。它们都可以设置子组件的对齐方式。重点需要了解它们有哪些对齐方式,以及如何对齐的。

布局行为
Row默认行为:在水平方向会尽可能大,大到会撑满parent;在垂直方向会尽可能小,小到能包裹住children。children在水平居左,垂直方向上居中。

Column默认行为:在垂直方向上会尽可能大,大到会撑满parent;在水平方向会尽可能小,小到能包裹住children。children在垂直居上,水平方向上居中。

mainAxisAlignment 主轴对齐方式
crossAxisAlignment 纵轴对齐方式
详细

async,await,Future

异步操作让您的程序在等待另一个操作完成的同时完成工作:
例:通过网络获取数据。写入数据库。从文件中读取数据。

  • Future对象表示异步操作的结果,我们通常通过then()来处理返回的结果

  • async用于标明函数是一个异步函数,其返回值类型是Future类型

  • await用来等待耗时操作的返回结果,这个操作会阻塞到后面的代码

  • Future 表示异步操作的结果,可以有两种状态:未完成或已完成。
    未完成:
    当你调用一个异步函数时,它会返回一个未完成的Future。那个Future正在等待函数的异步操作完成或抛出错误。
    完成:
    如果异步操作成功,future 以一个值结束。否则,它会以错误完成。
    完成返回的值:
    type 的 future 以 typeFuture的值结束T。例如,带有类型的未来Future会产生一个字符串值。如果未来不产生可用值,那么未来的类型是 Future.
    错误:
    如果函数执行的异步操作由于任何原因失败,future 会以错误结束。

关键术语:

同步操作:同步操作阻止其他操作执行,直到它完成。
同步函数:同步函数只执行同步操作。
异步操作:一旦启动,异步操作允许在完成之前执行其他操作。
异步函数:异步函数至少执行一个异步操作,也可以执行同步操作。
详细

Stream 流异步通信 StreamController

Stream 是一个抽象类,用来表示一个序列的异步数据,Stream流分类:

  • 单订阅流(Single Subscription),这种流最多只能有一个监听器(listener)
  • 多订阅流(Broadcast),这种流可以有多个监听器监听(listener)

Stream可以接受任何类型的数据,Stream 有同步流和异步流之分,它们的区别在于同步流会在执行 add,addError 或 close 方法时会立即发送事件,而异步流总是在事件队列中的代码执行完成后再发送事件。
详细

Animation动画

1、Animation
Animation是一个抽象(abstract)类,它不能直接实例化,比较常用得Animation类是Animation。Animation对象再一段时间内生成一个区间值。Animation得输出可以是线性得,也可以是非线性得,因此Animation本身和UI渲染没有任何关系,它拥有动画当前值和状态。通过给Animation对象添加监听器,可以监听动画得每一帧及动画状态。添加监听得方法有:

addListener():每一帧都会调用,一般会在其中调用setState()来触发UI重建;
addStatusListener():添加动画状态改变监听器,当动画状态开始
结束、正向、反向发生变化时调用。

2、Curve
动画得过程时线性得还是非线性得是由Curve确定得,Curve得作用和android中得Interpolator(插值)时一样得,负责控制动画变化得速率,通俗地讲就是使动画得效果能够以匀速、加速、抛物线等各种速率变化。
在这里插入图片描述

使用CurvedAnimation来指定动画曲线,代码如下:

animation = CurvedAnimation(parent: animationController, curve: Curves.bounceIn),

3、AnmationController
AnmationController使动画控制器,控制动画得播放、停止等。AnmationController继承自Animation,是一个特殊得Animation对象,屏幕刷新得每一帧都会生成一个新得值,默认情况下它会线性地生成0.0~1.0的值。

4、Tween
AnimationController继承自Anmation,输出的值只能为double类型。如果要求动画的效果是颜色变化,这时候AnimationController并不能满足需求,而Tween继承自Animatable,它提供了evaluate方法以获取当前映射值。使用Tween对象需要调用animate方法传入控制器对象,并返回一个animation。
5、AnimatedList
AnimatedList:列表中数据发生变化时加入过渡动画。AnimatedList得构建首先需要itemBuilder,itemBuilder是一个函数,列表的每一个索引会调用,这个函数有一个animation参数,可以设置成任何一个动画。如果初始的时候数据不为空,AnimatedList的构建需要initialItemCount,initialItemCount表示数据的数量。当有数据添加或者删除时,调用AnimatedListState的对应的方法:

AnimatedListState.insertItem
AnimatedListState.removeItem

详细

Container

Container(容器控件)在Flutter是经常使用的控件,它就相当于我们HTML里的

标签。用来放置widget的容器,有padding、margin、位置、大小等参数。

详细

各种按钮

  • FloatingActionButton 圆形的按钮,一般出现在屏幕内容的前面,用来处理界面中最常用、最基础的用户动作。
  • RaisedButton 凸起的按钮,默认带有灰色背景,被点击后灰色背景会加深。
  • FlatButton 扁平化的按钮,默认透明背景,被点击后会呈现灰色背景。
  • OutlineButton OutlineButton默认有一个边框,不带阴影且背景透明。按下后,边框颜色会变亮、同时出现背景和阴影(较弱)
  • IconButton IconButton是一个可点击的Icon,不包括文字,默认没有背景,获取焦点后显示背景。
  • 带图标的按钮 RaisedButton、FlatButton、OutlineButton都有一个icon 构造函数,通过它可以创建带图标的按钮。
  • InkWell 给其他控件添加水波纹点击效果
 const FlatButton({
    Key key,
    @required VoidCallback onPressed, // 点击回调
    VoidCallback onLongPress,//长按回调
    ValueChanged<bool> onHighlightChanged,
    ButtonTextTheme textTheme,
    Color textColor,//按钮文字颜色
    Color disabledTextColor,//按钮禁用时的文字颜色
    Color color,//按钮背景颜色
    Color disabledColor,//按钮禁用时的背景颜色
    Color focusColor,//按钮按下时的背景颜色
    Color hoverColor,//悬停时的背景颜色
    Color highlightColor,//高亮时背景颜色
    Color splashColor,//点击时,水波动画中水波的颜色
    Brightness colorBrightness,//按钮主题,默认是浅色主题
    EdgeInsetsGeometry padding,//按钮的内边距
    ShapeBorder shape,//外形
    Clip clipBehavior = Clip.none,
    FocusNode focusNode,
    bool autofocus = false,
    MaterialTapTargetSize materialTapTargetSize,
    @required Widget child,//按钮的内容
  }) 
其中shape有下面三种:

RoundedRectangleBorder:圆形矩形边框
ContinuousRectangleBorder:连续矩形边框
BeveledRectangleBorder : 斜角矩形边框

 RaisedButton(
	  color: Colors.blue, // 按钮背景色
	  highlightColor: Colors.blue[700],// 按钮高亮后的背景色
	  colorBrightness: Brightness.dark,// 使用深色主题,保证按钮文字颜色为浅色
	  splashColor: Colors.grey,// 点击时,水波动画中水波的颜色
	  child: Text("Submit"),// 文本
	  shape: RoundedRectangleBorder(
	      borderRadius: BorderRadius.circular(20.0)), //圆角矩形
	  onPressed: () {},
)

FlatButton(
   color: Colors.yellow, //设置背景色为黄色
   shape: ContinuousRectangleBorder(
       borderRadius: BorderRadius.circular(20.0)), //设置斜角矩形边框
   colorBrightness: Brightness.light, //使用亮色主题,保证按钮文字颜色为深色
   onPressed: () {},
   child: Icon(Icons.add)
)


详细

showDialog弹框

详细

Dio网络通信

dio是一款Flutter 网络请求框架,一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等

Dart语言

  • Dart是单线程的语言,所以如果线程中顺序执行的时候如果遇到一些耗时阻塞的操作,比如数据请求,延时操作等,就会产生卡顿,所以用异步来解决。
  • 级联运算符 (…) 可以让你在同一个对象上连续调用多个对象的变量或方法。

我项目中所用

  //强制横屏
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeLeft,
    DeviceOrientation.landscapeRight
  ]);
  
  //隐藏顶部状态栏
  SystemChrome.setEnabledSystemUIOverlays([]);
  
  //屏幕宽高
  MediaQuery.of(context).size.width
  MediaQuery.of(context).size.height
  • SizedBox 用来设置两个控件之间的间距
  • AppBar 设置导航栏标题、导航栏菜单、导航栏底部的 Tab
  • Text
  • RaisedButton (onPressed属性)(child 子组件)
  • Column和Row
  • Center 将子控件放在其内部中心,里面只能放一个child,但是child里面可以放Container
  • Container 容器
  • BoxDecoration 容器decoration属性中可以添加这个容器的装饰
  • BoxFit.fill 布满整个父容器
  • DecorationImage 容器的背景
  • InputDecoration 输入框的装饰
  • OutlineInputBorder 输入框的外边框
  • borderRadius 圆角
  • AssetImage 引用图片
  • Stack 层叠布局
  • Positioned 定位
  • Text 文本
  • TextStyle 文本样式
  • TextField 文本输入框
  • CustomPaint
  • Opacity 透明度
  • FlatButton 按钮
  • setState 整个页面的刷新
  • TextField 文字输入框
  • onChanged 输入内容变化时,调用函数进行改变
  • onPressed 按钮按下时,调用函数改变
  • onConfirm 确定事件
  • Color.fromARGB(255, 100, 219, 229) 颜色
  • Icon 图片
  • showDialog 对话框
  • AlertDialog 弹框
  • PageView 轮播的组件
  • PageController 轮播控制器
  • nextPage 轮播下一张图
  • AudioCache和AudioPlayer 音频播放控制
  • Duration 持续时间
  • Timer 时间控制器
  • GridView 表格组件
  • StatefulWidget 有状态的Widget树,可以更新视图
  • StatelessWidget 无状态的Widget树
  • StreamController 流控制器
  • StreamBuilder 流将要更新的组件,写在这个下面,需要绑定流控制器
  • cancel 时间控制器的销毁
  • close 流控制器的关闭销毁
  • stop音频控制器的停止
  • Curves 动画的过渡方式
  • ClipRRect 裁剪布局 将 child 剪裁为圆角矩形
  • GestureDetector 手势控制
  • onTapDown 手指按下
  • onTap 手指抬起
  • onTapCancel 手指按下后滑动移出
  • PieChatWidget echarts中的饼图
  • Switch 开关
  • showDatePicker 日期控件
  • DateTime 日期
  • SingleChildScrollView 滚动组件
  • ListView 列表控件,可上下滑动
  • Padding 可以设置边距问题
  • EdgeInsets.only(left: 20,bottom: 20,top: 20,right: 20) 设置边距
  • Radio 单选按钮
  • RadioOptions 一组按钮
  • RichText 富文本标签
  • TextSpan 富文本标签中的某一段落

项目插件

  sdk: ">=2.11.0 <3.0.0" #适配空安全(允许关闭空安全)
  cupertino_icons: ^1.0.2
  shake_animation_widget: ^2.1.2 #底部向上动画弹出
  date_format: ^1.0.9 #格式化时间的库
  intl: ^0.16.1 #格式化时间的库
  sqflite: ^1.1.3 #数据库
  flutter_datetime_picker: 1.5.1 #时间选择器
  audioplayers: ^0.16.1 #音频插件
  flutter_echart: ^1.0.0 #图表插件
  dio: ^3.0.0 #网络请求
  tencent_kit: ^2.1.0 #腾讯插件
  circle_progress: ^0.0.1 #倒计时进度条

本人项目细节

最终效果

链接

登录界面雪花

步骤:

  • 创建一个集合用来保存气泡生成随机数
  • 创建动画控制器
  • 执行刷新监听
  • 开启气泡的运动
  • initData 初始化 (获取随机透明度白色)(随机位置,半径,下落速度)
  • 创建画布绘制

代码链接

详细

登录成功和失败的弹框

代码链接

加载倒计时动画

代码链接

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值