为了账号安全,请及时绑定邮箱和手机立即绑定

[-Flutter自定义组件-] Flutter中四十行代码能做什么?

标签:
Android

看完此文,你一定会会惊讶于Flutter在视图方面是多么优雅
你拿之与Android原生或iOS原生相比,简直天差地别,就像蒸汽时代VS电器时代
下面就是四十行代码能够发挥出的威力,其中每个文字都可以替换成任意组件,Flutter(颤抖)吧!


https://img1.sycdn.imooc.com//5d52bd2d0001f39500880052.jpg



1.TreeWidget的思路

以前Android原生,跟过鸿阳的视频做过类似的树状效果,当时还是小白,听得云里雾里,还好最后实现了。
既然Flutter的视图如此强大,那到底能有多强大,组件的复用如何秒杀原生视图
对于这个树状组件,开始设计时我也很头疼,也走错了路,想一下将所有节点显示,然后控制显隐
然未果,可以说山重水复疑无路,柳暗花明又一村。灵光一现,组件不就是用来拼合的吗?
于是我不再注重一统全局,而是化整为零,各个击破。结果证明这样是对的。


1.1:Node对象

这是最初设计时就意识到的,我必须通过一个对象去控制节点,
这个Node中记录自身Widget和它内部的若干Node,记住是Node!!!

///记录节点信息的Node类
class Node {
  Widget me;//节点自身Widget
  List<Node> children;//节点所包含的Node
  Node({this.me, this.children});
}

1.2:NodeWidget组件对象

NodeWidget的功能是展示一个Node节点,点击时可以将子Node展示出来,再点击收拢Node

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;
    }
  }
}

1.3:NodeWidget的使用

这样化万为一,再由一聚万。看似无用,却变幻无穷,妙哉,妙哉。


5d52bcfc00019b7200360062.jpg


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,);

2.TextTreeWidget的封装

上面在使用上有一点点麻烦,所以简单加个箭头图标再封装一下。

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 ]
    );
 }
}

使用

感觉这是在封装结构,而不是封装组件,可以将组件和结构进行抽离,这样拓展性会非常好。
感觉这里不是最好的状态,以后有时间再重构这四十行代码吧。


https://img1.sycdn.imooc.com//5d52bd4b0001f39500880052.jpg


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);
  },
)



点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消