写点什么

Flutter 嵌套深?扩展函数了解一下,面试字节跳动 Android 工程师该怎么准备

用户头像
Android架构
关注
发布于: 46 分钟前

buildItem("billy"),


],


),


),


),


);


}


Container buildItem(String name) {


return Container(


color: Colors.white,


padding: EdgeInsets.all(20),


child: Row(


crossAxisAlignment: CrossAxisAlignment.center,


children: <Widget>[


Icon(Icons.phone),


Text(name),


],


),


);


}


}


还能不能继续优化呢?


[](


)自定义扩展函数




举个例子:想要给下面这段代码中的第 2 个Textwidget 加上marginTop:10属性


@override


Widget build(BuildContext context) {


return Container(


padding: EdgeInsets.all(10),


child: Column(


children: <Widget>[


Text('billy'),


Text('say hello'), //add margin top??


],


),


);


}


此时,我内心希望可以这样写:



显然,flutter 不支持这么写,幸运的是:[dart2.7 发布](


)时正式宣布支持扩展函数(Extension Methods)


实际上从 dart 2.6.0 就开始支持扩展函数了


如果 pubspec.yaml 中设置的 dart 版本低于 2.6.0 则会出现警告提示


如:


environment:


sdk: ">=2.1.0 <3.0.0"


警告提示:


Extension methods weren’t supported until version 2.6.0


先来定义一个扩展函数


extension WidgetExt on Widget {


Container intoContainer({


//复制 Container 构造函数的所有参数(除了 child 字段)


Key key,


AlignmentGeometry alignment,


EdgeInsetsGeometry padding,


Color color,


Decoration decoration,


Decoration foregroundDecoration,


double width,


double height,


BoxConstraints constraints,


EdgeInsetsGeometry margin,


Matrix4 transform,


}) {


//调用 Container 的构造函数,并将当前 widget 对象作为 child 参数


return Container(


key: key,


alignment: alignment,


padding: padding,


color: color,


decoration: decoration,


foregroundDecoration: foregroundDecoration,


width: width,


height: height,


constraints: constraints,


margin: margin,


transform: transform,


child: this,


);


}


}


现在,所有 widget 对象都多了一个intoContainer(...)扩展函数,而且参数与Container构造方法一致,于是,我们就可以这样写了:



除了Container,其它容器也可以通过同样的方式来扩展。于是,编程体验大大提升。


还可以支持链式调用:


Text("billy")


.intoExpanded(flex: 1)


.intoContainer(color: Colors.white)


有些 widget 有多个子 widget (children), 可以添加如下的扩展函数:


extension WidgetExt on Widget {


//添加一个相邻的 widget,返回 List<Widget>


List<Widget> addNeighbor(Widget widget) {


return <Widget>[this, widget];


}


//添加各种单


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


child 的 widget 容器


//如:Container、Padding 等...


}


extension WidgetListExt<T extends Widget> on List<T> {


//子 List<Widget>列表中再添加一个相邻的 widget,并返回当前列表


List<Widget> addNeighbor(Widget widget) {


return this..add(widget);


}


Row intoRow({


Key key,


MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,


MainAxisSize mainAxisSize = MainAxisSize.max,


CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,


TextDirection textDirection,


VerticalDirection verticalDirection = VerticalDirection.down,


TextBaseline textBaseline,


}) {


return Row(


key: key,


mainAxisAlignment: mainAxisAlignment,


mainAxisSize: mainAxisSize,


crossAxisAlignment: crossAxisAlignment,


textDirection: textDirection,


verticalDirection: verticalDirection,


textBaseline: textBaseline,


children: this,


);


}


//添加其它多 child 的 widget 容器


//如:Column、ListView 等...


}


[](


)使用扩展函数解决嵌套过深的问题




回到本文最初的嵌套地狱,现在我们的代码可以写成这样


class Test extends StatelessWidget {


@override


Widget build(BuildContext context) {


return Scaffold(


appBar: AppBar(title: Text('Demo'),),


body: buildItem("amy")


.addNeighbor(buildItem("billy"),)


.intoListView()


.intoOffstage(offstage: false)


.intoContainer()


);


}


Container buildItem(String name) {


return Icon(Icons.phone)


.addNeighbor(Text(name))


.intoRow(crossAxisAlignment: CrossAxisAlignment.center,)


.intoContainer(color: Colors.white, padding: EdgeInsets.all(20),);


}


}


为了让我们的代码更加符合链式编程风格,再定义一个静态方法吧


class WidgetChain {


static Widget addNeighbor(Widget widget) {


return widget;


}


}


另外,再定义一个从数据到 widget 的映射扩展方法


extension ListExt<T> on List<T> {


List<Widget> buildAllAsWidget(Widget Function(T) builder) {


return this.map<Widget>((item) {


return builder(item);


}).toList();


}


}


现在,代码是这样的:


class Test extends StatelessWidget {


@override


Widget build(BuildContext context) {


return Scaffold(


appBar: AppBar(title: Text('Demo'),),


body: ["amy", "billy"]


.buildAllAsWidget((name) =>


WidgetChain


.addNeighbor(Icon(Icons.phone))


.addNeighbor(Text(name))

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Flutter嵌套深?扩展函数了解一下,面试字节跳动Android工程师该怎么准备