[-Flutter自組篇-] Flutter中四十行代碼能作什麼?

看完此文,你必定會會驚訝於Flutter在視圖方面是多麼優雅
你拿之與Android原生或iOS原生相比,簡直天差地別,就像蒸汽時代VS電器時代
下面就是四十行代碼可以發揮出的威力,其中每一個文字均可以替換成任意組件,Flutter(顫抖)吧!node


1.TreeWidget的思路

之前Android原生,跟過鴻陽的視頻作過相似的樹狀效果,當時仍是小白,聽得雲裏霧裏,還好最後實現了。
既然Flutter的視圖如此強大,那到底能有多強大,組件的複用如何秒殺原生視圖
對於這個樹狀組件,開始設計時我也很頭疼,也走錯了路,想一下將全部節點顯示,而後控制顯隱
然未果,能夠說山重水複疑無路,柳暗花明又一村。靈光一現,組件不就是用來拼合的嗎?
因而我再也不注重一統全局,而是化整爲零,各個擊破。結果證實這樣是對的。bash


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展現出來,再點擊收攏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;
    }
  }
}
複製代碼

1.3:NodeWidget的使用

這樣化萬爲一,再由一聚萬。看似無用,卻千變萬化,妙哉,妙哉。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,);
複製代碼

2.TextTreeWidget的封裝

上面在使用上有一點點麻煩,因此簡單加個箭頭圖標再封裝一下。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

相關文章
相關標籤/搜索