/// Tree view widget library library tree_view; import 'package:aitrainer_app/util/common.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'dart:math' as math; class TreeView extends InheritedWidget { final List children; final bool startExpanded; TreeView({ Key key, @required List children, bool startExpanded = false, }) : this.children = children, this.startExpanded = startExpanded, super( key: key, child: _TreeViewData( children: children, ), ); static TreeView of(BuildContext context) { //return context.inheritFromWidgetOfExactType(TreeView); return context.dependOnInheritedWidgetOfExactType(aspect: TreeView); } @override bool updateShouldNotify(TreeView oldWidget) { if (oldWidget.children == this.children && oldWidget.startExpanded == this.startExpanded) { return false; } return true; } } class _TreeViewData extends StatelessWidget { final List children; _TreeViewData({ this.children, }); @override Widget build(BuildContext context) { return ListView.builder( itemCount: children.length, itemBuilder: (context, index) { return children.elementAt(index); }, ); } } class TreeViewChild extends StatefulWidget { final bool startExpanded; final Widget parent; final List children; final VoidCallback onTap; TreeViewChild({ @required this.parent, @required this.children, this.startExpanded, this.onTap, Key key, }) : super(key: key) { assert(parent != null); assert(children != null); } @override TreeViewChildState createState() => TreeViewChildState(); TreeViewChild copyWith( TreeViewChild source, { bool startExpanded, Widget parent, List children, VoidCallback onTap, }) { return TreeViewChild( parent: parent ?? source.parent, children: children ?? source.children, startExpanded: startExpanded ?? source.startExpanded, onTap: onTap ?? source.onTap, ); } } class TreeViewChildState extends State with Common, SingleTickerProviderStateMixin { bool isExpanded; final GlobalKey listKey = GlobalKey(); Color _color; double _opacity = 0; /* List listWidgets; */ AnimationController _controller; Animation sizeAnimation; @override void initState() { super.initState(); isExpanded = widget.startExpanded; _color = Colors.transparent; _opacity = 0; /* listWidgets = List.from(widget.children); */ /* _controller = AnimationController( duration: const Duration(seconds: 1), vsync: this, ); sizeAnimation = Tween(begin: 0.0, end: 1.0).animate(_controller);*/ } @override void didChangeDependencies() { isExpanded = widget.startExpanded ?? TreeView.of(context).startExpanded; super.didChangeDependencies(); } @override Widget build(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ GestureDetector( child: widget.parent, onTap: widget.onTap ?? () => toggleExpanded(), ), Flexible( child: Container( /*animation: _controller, builder: (BuildContext context, Widget child) { return Transform.scale( scale: _controller.value, child: child, ); },*/ /* color: _color, duration: Duration(seconds: 2), curve: Curves.easeInOut,*/ //height: double.infinity, /*child: isExpanded //animateChildren() ? Column( mainAxisSize: MainAxisSize.min, children: widget.children, ) : Offstage(),*/ child: /*AnimatedCrossFade( firstChild: Column( mainAxisSize: MainAxisSize.min, children: widget.children, ), secondChild: Offstage(), duration: Duration(milliseconds:800), crossFadeState: isExpanded ? CrossFadeState.showFirst : CrossFadeState.showSecond, )*/ AnimatedSwitcher( duration: Duration(milliseconds:900), reverseDuration: Duration(milliseconds:500), switchInCurve: Curves.easeIn, child: isExpanded ? Column( mainAxisSize: MainAxisSize.min, children: widget.children, ) : Offstage(), ), ), ) ], ); } /*AnimatedList animateChildren() { return AnimatedList( shrinkWrap: true, key: listKey, initialItemCount: listWidgets.length, itemBuilder: (context, index, animation) { return slideIt(animation, listWidgets[index]); }, ); } Widget slideIt(Animation animation, Widget element) { return SizeTransition( sizeFactor: animation, axis: Axis.vertical, child: element, ); }*/ void toggleExpanded() { setState(() { this.isExpanded = !this.isExpanded; _color = isExpanded ? Colors.black12 : Colors.transparent; _opacity = isExpanded ? 1 : 0; /* if ( isExpanded == false ) { _removeAllItems(); } else { //_addAllItems(); listWidgets = List.from(widget.children); }*/ }); } /* void _removeAllItems() { final int itemCount = widget.children.length; for (var i = 0; i < itemCount; i++) { Widget itemToRemove = listWidgets[0]; listKey.currentState.removeItem(0, (BuildContext context, Animation animation) => slideIt(animation, itemToRemove), duration: const Duration(milliseconds: 250), ); listWidgets.removeAt(0); } } void _addAllItems() { final int itemCount = widget.children.length; for (var i = 0; i < itemCount; i++) { listKey.currentState.insertItem(0); listWidgets.insert(0, widget.children[i]); } }*/ }