|
2 | 2 | // Use of this source code is governed by a BSD-style license that can be |
3 | 3 | // found in the LICENSE file. |
4 | 4 |
|
5 | | -import 'package:flutter/gestures.dart'; |
6 | 5 | import 'package:flutter/material.dart'; |
7 | | -import 'package:two_dimensional_scrollables/two_dimensional_scrollables.dart'; |
8 | 6 |
|
9 | | -// Print statements are only for illustrative purposes, not recommended for |
10 | | -// production applications. |
11 | | -// ignore_for_file: avoid_print |
| 7 | +import 'table_view/table_explorer.dart'; |
| 8 | +import 'tree_view/tree_explorer.dart'; |
12 | 9 |
|
13 | 10 | void main() { |
14 | | - runApp(const TableExampleApp()); |
| 11 | + runApp(const ExampleApp()); |
15 | 12 | } |
16 | 13 |
|
17 | | -/// A sample application that utilizes the TableView API. |
18 | | -class TableExampleApp extends StatelessWidget { |
19 | | - /// Creates an instance of the TableView example app. |
20 | | - const TableExampleApp({super.key}); |
| 14 | +/// A sample application that utilizes the TableView and TreeView APIs. |
| 15 | +class ExampleApp extends StatelessWidget { |
| 16 | + /// Creates an instance of the example app. |
| 17 | + const ExampleApp({super.key}); |
21 | 18 |
|
22 | 19 | @override |
23 | 20 | Widget build(BuildContext context) { |
24 | 21 | return MaterialApp( |
25 | | - title: 'Table Example', |
| 22 | + title: '2D Scrolling Examples', |
26 | 23 | theme: ThemeData( |
27 | | - useMaterial3: true, |
| 24 | + colorScheme: ColorScheme.fromSeed(seedColor: Colors.purple), |
| 25 | + appBarTheme: AppBarTheme(backgroundColor: Colors.purple[50]), |
28 | 26 | ), |
29 | | - home: const TableExample(), |
| 27 | + home: const ExampleHome(), |
| 28 | + routes: <String, WidgetBuilder>{ |
| 29 | + '/table': (BuildContext context) => const TableExplorer(), |
| 30 | + '/tree': (BuildContext context) => const TreeExplorer(), |
| 31 | + }, |
30 | 32 | ); |
31 | 33 | } |
32 | 34 | } |
33 | 35 |
|
34 | | -/// The class containing the TableView for the sample application. |
35 | | -class TableExample extends StatefulWidget { |
| 36 | +/// The home page of the application, which directs to the tree or table |
| 37 | +/// explorer. |
| 38 | +class ExampleHome extends StatelessWidget { |
36 | 39 | /// Creates a screen that demonstrates the TableView widget. |
37 | | - const TableExample({super.key}); |
38 | | - |
39 | | - @override |
40 | | - State<TableExample> createState() => _TableExampleState(); |
41 | | -} |
42 | | - |
43 | | -class _TableExampleState extends State<TableExample> { |
44 | | - late final ScrollController _verticalController = ScrollController(); |
45 | | - int _rowCount = 20; |
| 40 | + const ExampleHome({super.key}); |
46 | 41 |
|
47 | 42 | @override |
48 | 43 | Widget build(BuildContext context) { |
49 | 44 | return Scaffold( |
50 | 45 | appBar: AppBar( |
51 | | - title: const Text('Table Example'), |
52 | | - ), |
53 | | - body: Padding( |
54 | | - padding: const EdgeInsets.symmetric(horizontal: 50), |
55 | | - child: TableView.builder( |
56 | | - verticalDetails: |
57 | | - ScrollableDetails.vertical(controller: _verticalController), |
58 | | - cellBuilder: _buildCell, |
59 | | - columnCount: 20, |
60 | | - columnBuilder: _buildColumnSpan, |
61 | | - rowCount: _rowCount, |
62 | | - rowBuilder: _buildRowSpan, |
63 | | - ), |
64 | | - ), |
65 | | - persistentFooterButtons: <Widget>[ |
66 | | - TextButton( |
67 | | - onPressed: () { |
68 | | - _verticalController.jumpTo(0); |
69 | | - }, |
70 | | - child: const Text('Jump to Top'), |
71 | | - ), |
72 | | - TextButton( |
73 | | - onPressed: () { |
74 | | - _verticalController |
75 | | - .jumpTo(_verticalController.position.maxScrollExtent); |
76 | | - }, |
77 | | - child: const Text('Jump to Bottom'), |
78 | | - ), |
79 | | - TextButton( |
80 | | - onPressed: () { |
81 | | - setState(() { |
82 | | - _rowCount += 10; |
83 | | - }); |
84 | | - }, |
85 | | - child: const Text('Add 10 Rows'), |
86 | | - ), |
87 | | - ], |
88 | | - ); |
89 | | - } |
90 | | - |
91 | | - TableViewCell _buildCell(BuildContext context, TableVicinity vicinity) { |
92 | | - return TableViewCell( |
93 | | - child: Center( |
94 | | - child: Text('Tile c: ${vicinity.column}, r: ${vicinity.row}'), |
| 46 | + title: const Text('Tables & Trees'), |
95 | 47 | ), |
96 | | - ); |
97 | | - } |
98 | | - |
99 | | - TableSpan _buildColumnSpan(int index) { |
100 | | - const TableSpanDecoration decoration = TableSpanDecoration( |
101 | | - border: TableSpanBorder( |
102 | | - trailing: BorderSide(), |
| 48 | + body: Center( |
| 49 | + child: Column(children: <Widget>[ |
| 50 | + const Spacer(flex: 3), |
| 51 | + FilledButton( |
| 52 | + onPressed: () { |
| 53 | + // Go to table explorer |
| 54 | + Navigator.of(context).pushNamed('/table'); |
| 55 | + }, |
| 56 | + child: const Text('TableView Explorer'), |
| 57 | + ), |
| 58 | + const Spacer(), |
| 59 | + FilledButton( |
| 60 | + onPressed: () { |
| 61 | + // Go to tree explorer |
| 62 | + Navigator.of(context).pushNamed('/tree'); |
| 63 | + }, |
| 64 | + child: const Text('TreeView Explorer'), |
| 65 | + ), |
| 66 | + const Spacer(flex: 3), |
| 67 | + ]), |
103 | 68 | ), |
104 | 69 | ); |
105 | | - |
106 | | - switch (index % 5) { |
107 | | - case 0: |
108 | | - return TableSpan( |
109 | | - foregroundDecoration: decoration, |
110 | | - extent: const FixedTableSpanExtent(100), |
111 | | - onEnter: (_) => print('Entered column $index'), |
112 | | - recognizerFactories: <Type, GestureRecognizerFactory>{ |
113 | | - TapGestureRecognizer: |
114 | | - GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>( |
115 | | - () => TapGestureRecognizer(), |
116 | | - (TapGestureRecognizer t) => |
117 | | - t.onTap = () => print('Tap column $index'), |
118 | | - ), |
119 | | - }, |
120 | | - ); |
121 | | - case 1: |
122 | | - return TableSpan( |
123 | | - foregroundDecoration: decoration, |
124 | | - extent: const FractionalTableSpanExtent(0.5), |
125 | | - onEnter: (_) => print('Entered column $index'), |
126 | | - cursor: SystemMouseCursors.contextMenu, |
127 | | - ); |
128 | | - case 2: |
129 | | - return TableSpan( |
130 | | - foregroundDecoration: decoration, |
131 | | - extent: const FixedTableSpanExtent(120), |
132 | | - onEnter: (_) => print('Entered column $index'), |
133 | | - ); |
134 | | - case 3: |
135 | | - return TableSpan( |
136 | | - foregroundDecoration: decoration, |
137 | | - extent: const FixedTableSpanExtent(145), |
138 | | - onEnter: (_) => print('Entered column $index'), |
139 | | - ); |
140 | | - case 4: |
141 | | - return TableSpan( |
142 | | - foregroundDecoration: decoration, |
143 | | - extent: const FixedTableSpanExtent(200), |
144 | | - onEnter: (_) => print('Entered column $index'), |
145 | | - ); |
146 | | - } |
147 | | - throw AssertionError( |
148 | | - 'This should be unreachable, as every index is accounted for in the switch clauses.'); |
149 | | - } |
150 | | - |
151 | | - TableSpan _buildRowSpan(int index) { |
152 | | - final TableSpanDecoration decoration = TableSpanDecoration( |
153 | | - color: index.isEven ? Colors.purple[100] : null, |
154 | | - border: const TableSpanBorder( |
155 | | - trailing: BorderSide( |
156 | | - width: 3, |
157 | | - ), |
158 | | - ), |
159 | | - ); |
160 | | - |
161 | | - switch (index % 3) { |
162 | | - case 0: |
163 | | - return TableSpan( |
164 | | - backgroundDecoration: decoration, |
165 | | - extent: const FixedTableSpanExtent(50), |
166 | | - recognizerFactories: <Type, GestureRecognizerFactory>{ |
167 | | - TapGestureRecognizer: |
168 | | - GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>( |
169 | | - () => TapGestureRecognizer(), |
170 | | - (TapGestureRecognizer t) => |
171 | | - t.onTap = () => print('Tap row $index'), |
172 | | - ), |
173 | | - }, |
174 | | - ); |
175 | | - case 1: |
176 | | - return TableSpan( |
177 | | - backgroundDecoration: decoration, |
178 | | - extent: const FixedTableSpanExtent(65), |
179 | | - cursor: SystemMouseCursors.click, |
180 | | - ); |
181 | | - case 2: |
182 | | - return TableSpan( |
183 | | - backgroundDecoration: decoration, |
184 | | - extent: const FractionalTableSpanExtent(0.15), |
185 | | - ); |
186 | | - } |
187 | | - throw AssertionError( |
188 | | - 'This should be unreachable, as every index is accounted for in the switch clauses.'); |
189 | 70 | } |
190 | 71 | } |
0 commit comments