136 lines
3.0 KiB
Dart
136 lines
3.0 KiB
Dart
/// Tree view widget library
|
|
library tree_view;
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
|
|
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;
|
|
|
|
const _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> {
|
|
bool isExpanded;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
isExpanded = widget.startExpanded;
|
|
}
|
|
|
|
@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(),
|
|
),
|
|
AnimatedContainer(
|
|
duration: Duration(milliseconds: 400),
|
|
child: isExpanded
|
|
? Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: widget.children,
|
|
)
|
|
: Offstage(),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
void toggleExpanded() {
|
|
setState(() {
|
|
this.isExpanded = !this.isExpanded;
|
|
});
|
|
}
|
|
}
|