看完此文,你必定会会惊讶于Flutter在视图方面是多么优雅
你拿之与Android原生或iOS原生相比,简直天差地别,就像蒸汽时代VS电器时代
下面就是四十行代码可以发挥出的威力,其中每一个文字均可以替换成任意组件,Flutter(颤抖)吧!node
之前Android原生,跟过鸿阳的视频作过相似的树状效果,当时仍是小白,听得云里雾里,还好最后实现了。
既然Flutter的视图如此强大,那到底能有多强大,组件的复用如何秒杀原生视图
对于这个树状组件,开始设计时我也很头疼,也走错了路,想一下将全部节点显示,而后控制显隐
然未果,能够说山重水复疑无路,柳暗花明又一村。灵光一现,组件不就是用来拼合的吗?
因而我再也不注重一统全局,而是化整为零,各个击破。结果证实这样是对的。bash
这是最初设计时就意识到的,我必须经过一个对象去控制节点,
这个Node中记录自身Widget和它内部的若干Node,记住是Node!!!
微信
///记录节点信息的Node类
class Node {
Widget me;//节点自身Widget
List<Node> children;//节点所包含的Node
Node({this.me, this.children});
}
复制代码
NodeWidget的功能是展现一个Node节点,点击时能够将子Node展现出来,再点击收拢Nodeide
class NodeWidget extends StatefulWidget {
NodeWidget({Key key, this.node}) : super(key: key);
final Node node;
@override
_NodeWidgetState createState() => _NodeWidgetState();
}
class _NodeWidgetState extends State<NodeWidget> {
Node node;
bool showList = false;
@override
Widget build(BuildContext context) {
return showNode(widget.node, showList);
}
Widget showNode(Node node, bool show) {
var me = InkWell(child: node.me,
onTap: () {
showList = !showList;
print(showList);
setState(() {});});
if (show) {
var children = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: node.children.map((node) => node.me).toList(),);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[me,
Padding(padding: EdgeInsets.only(left: 20),
child: children,)],);
} else {
return me;
}
}
}
复制代码
这样化万为一,再由一聚万。看似无用,却千变万化,妙哉,妙哉。post
var friendsNode=[Node(me: Text("张三丰")),Node(me: Text("独孤九剑")),Node(me: Text("令狐冲")),Node(me: Text("魏无羡"))];
var node = Node(me: Text("个人好友",),
children: [
Node(me: NodeWidget(node: Node(me: Text("损友",), children: friendsNode))),
Node(me: Text("好友")), Node(me: Text("道友",)), Node(me: Text("漫友",)), Node(me: Text("普友",)),
]);
var show = NodeWidget(node: node,);
复制代码
上面在使用上有一点点麻烦,因此简单加个箭头图标再封装一下。ui
class TextTreeWidget extends StatefulWidget {
TextTreeWidget({Key key, this.node, this.onClickCallback}) : super(key: key);
final Node node;
final OnClickCallback onClickCallback;
factory TextTreeWidget.fromStr(String me,List<String> children){
return TextTreeWidget(node: Node(me: Text(me),children: children.map((e)=>Node(me: Text(e))).toList
}
@override
_TextTreeWidgetState createState() => _TextTreeWidgetState();
}
class _TextTreeWidgetState extends State<TextTreeWidget> {
Node node;
bool showList = false;
@override
Widget build(BuildContext context) {
return showNode(widget.node, showList);
}
Widget showNode(Node node, bool show) {
var me = InkWell(
child: formWidget(node.me),
onTap: () {
showList = !showList;
if (widget.onClickCallback != null) {
widget.onClickCallback(!showList);
}
setState(() {});
});
if (show) {
var children = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: node.children.map((node) => node.me).toList(), );
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[ me,
Padding(padding: EdgeInsets.only(left: 30),child: children,],
);
} else {return me;}
}
Widget formWidget(Widget me) {
return Row(crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Transform.rotate(
angle: !showList ? 0 : 90 / 180 * pi,
child: Icon(Icons.arrow_right), ),
me ]
);
}
}
复制代码
感受这是在封装结构,而不是封装组件,能够将组件和结构进行抽离,这样拓展性会很是好。
感受这里不是最好的状态,之后有时间再重构这四十行代码吧。this
var node = Node(me: Text("个人好友"),
children: [
Node(me: TextTreeWidget.fromStr("损友",["张三丰","独孤九剑","令狐冲","魏无羡"])),
Node(me: TextTreeWidget.fromStr("好友",["西施","杨玉环","王昭君","貂蝉"])),
Node(me: Text("道友",)), Node(me: Text("漫友",)), Node(me: Text("普友",)),]);
var show = TextTreeWidget(
node: node,
onClickCallback: (closed) {
print(closed);
},
)
复制代码
本文到此接近尾声了,若是想快速尝鲜Flutter,《Flutter七日》会是你的必备佳品;若是想细细探究它,那就跟随个人脚步,完成一次Flutter之旅。
另外本人有一个Flutter微信交流群,欢迎小伙伴加入,共同探讨Flutter的问题,本人微信号:zdl1994328
,期待与你的交流与切磋。spa