Last active
August 11, 2021 22:20
-
-
Save termslang/2a2c611b8e1ddb101f955d2f625c9b19 to your computer and use it in GitHub Desktop.
Solution to assignment https://workflowy.com/s/render-tree/rUSXOW3O9NKYBv6Z
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
/// Globals | |
Key selectedNode = UniqueKey(); | |
Set<Key> selectedSubnodes = Set(); | |
List<Node> nodes = [ | |
Node('A', [ | |
Node('A1'), | |
Node('A2', [ | |
Node('A21'), | |
Node('A22'), | |
Node('A23', [Node('A231')]), | |
Node('A24'), | |
]), | |
]), | |
Node('B'), | |
Node('C', [ | |
Node('C1'), | |
Node('C2'), | |
Node('C3'), | |
]), | |
]; | |
/// Model | |
class Node { | |
final Key key = UniqueKey(); | |
String title = ''; | |
List<Node> nodes; | |
Node(this.title, [_nodes]) : this.nodes = _nodes == null ? [] : _nodes; | |
} | |
/// App | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: MyHomePage(title: 'TreeRendererWidget'), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
MyHomePage({Key? key, required this.title}) : super(key: key); | |
final String title; | |
@override | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
), | |
body: TreeRendererWidget(nodes: nodes)); | |
} | |
} | |
class TreeRendererWidget extends StatefulWidget { | |
final List<Node> nodes; | |
final int depth; | |
TreeRendererWidget({Key? key, required this.nodes, this.depth = 0}) : super(key: key); | |
@override | |
_TreeRendererWidgetState createState() => _TreeRendererWidgetState(); | |
} | |
class _TreeRendererWidgetState extends State<TreeRendererWidget> { | |
@override | |
Widget build(BuildContext context) { | |
var ancestralState = context.findRootAncestorStateOfType<_MyHomePageState>(); | |
return Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: widget.nodes.map((Node n) { | |
return Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
GestureDetector( | |
onTap: () { | |
ancestralState?.setState(() { | |
if (selectedNode == n.key) { | |
selectedNode = UniqueKey(); | |
selectedSubnodes.clear(); | |
} else { | |
selectedNode = n.key; | |
selectedSubnodes.clear(); | |
_addSubnode(n); | |
} | |
}); | |
}, | |
child: Container( | |
color: selectedNode == n.key | |
? Colors.red | |
: selectedSubnodes.contains(n.key) | |
? Colors.orange | |
: Colors.white, | |
child: Text( | |
' ' * widget.depth * 5 + '• ' + n.title, | |
style: TextStyle(fontSize: 30), | |
), | |
), | |
), | |
TreeRendererWidget(nodes: n.nodes, depth: widget.depth + 1) | |
], | |
); | |
}).toList(), | |
); | |
} | |
void _addSubnode(Node n) { | |
n.nodes.forEach((nn) { | |
selectedSubnodes.add(nn.key); | |
_addSubnode(nn); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment