241 lines
6.1 KiB
Dart
241 lines
6.1 KiB
Dart
/// 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<Widget> children;
|
|
final bool startExpanded;
|
|
|
|
TreeView({
|
|
Key key,
|
|
@required List<Widget> 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<Widget> 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<Widget> 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<Widget> 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<TreeViewChild> with Common, SingleTickerProviderStateMixin {
|
|
bool isExpanded;
|
|
final GlobalKey<AnimatedListState> listKey = GlobalKey<AnimatedListState>();
|
|
Color _color;
|
|
double _opacity = 0;
|
|
|
|
/* List<Widget> listWidgets; */
|
|
AnimationController _controller;
|
|
Animation<double> 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<double>(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: <Widget>[
|
|
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<double> 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<double> 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]);
|
|
}
|
|
}*/
|
|
|
|
}
|