OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 import 'dart:math' as math; | 5 import 'dart:math' as math; |
6 | 6 |
7 import 'package:sky/rendering/box.dart'; | 7 import 'package:sky/rendering/box.dart'; |
8 import 'package:sky/rendering/object.dart'; | 8 import 'package:sky/rendering/object.dart'; |
9 import 'package:sky/widgets/basic.dart'; | 9 import 'package:sky/widgets/basic.dart'; |
10 import 'package:sky/widgets/icon.dart'; | 10 import 'package:sky/widgets/icon.dart'; |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 } | 292 } |
293 return new TabBarWrapper( | 293 return new TabBarWrapper( |
294 children: tabs, | 294 children: tabs, |
295 selectedIndex: selectedIndex, | 295 selectedIndex: selectedIndex, |
296 backgroundColor: Theme.of(this).primary[500], | 296 backgroundColor: Theme.of(this).primary[500], |
297 indicatorColor: Theme.of(this).accent[200], | 297 indicatorColor: Theme.of(this).accent[200], |
298 textAndIcons: textAndIcons | 298 textAndIcons: textAndIcons |
299 ); | 299 ); |
300 } | 300 } |
301 } | 301 } |
302 | |
303 class TabNavigatorView { | |
304 TabNavigatorView({ this.label, this.content }); | |
305 | |
306 final TabLabel label; | |
307 final Function content; | |
Hixie
2015/06/27 00:12:38
Function doesn't have a return type. Make a typede
hansmuller
2015/06/29 16:49:42
Thanks, that's better than the names I had in mind
| |
308 | |
309 Widget buildContent() { | |
310 return content != null ? content() : null; | |
abarth-chromium
2015/06/27 00:27:36
Should we just build unconditionally? What does i
hansmuller
2015/06/29 16:49:42
I suppose it could mean that there's no view for t
| |
311 } | |
312 } | |
313 | |
314 class TabNavigator extends Component { | |
315 TabNavigator({ | |
316 String key, | |
317 this.views, | |
318 this.selectedIndex: 0, | |
319 this.onChanged | |
320 }) : super(key: key, stateful: true); | |
321 | |
322 List<TabNavigatorView> views; | |
323 int selectedIndex; | |
324 SelectedIndexChanged onChanged; | |
325 | |
326 void syncFields(TabNavigator source) { | |
327 views = source.views; | |
328 selectedIndex = source.selectedIndex; | |
329 onChanged = source.onChanged; | |
330 } | |
331 | |
332 void _selectedTabIndexChanged(int tabIndex) { | |
333 setState(() { | |
334 selectedIndex = tabIndex; | |
335 }); | |
336 if (onChanged != null) | |
337 onChanged(selectedIndex); | |
abarth-chromium
2015/06/27 00:27:36
I'm not sure it makes sense to do both of these.
| |
338 } | |
339 | |
340 Widget build() { | |
341 assert(views != null && views.isNotEmpty); | |
342 assert(selectedIndex >= 0 && selectedIndex < views.length); | |
343 | |
344 TabBar tabBar = new TabBar( | |
345 labels: views.map((view) => view.label).toList(), | |
Hixie
2015/06/27 00:12:38
Why toList()?
hansmuller
2015/06/29 16:49:42
I've changed the type of TabBar.labels to Iterable
| |
346 onChanged: _selectedTabIndexChanged, | |
abarth-chromium
2015/06/27 00:27:36
If you make that change, you can just pass onChang
| |
347 selectedIndex: selectedIndex | |
348 ); | |
349 | |
350 Widget content = views[selectedIndex].buildContent(); | |
351 return new Flex( | |
352 <Widget>[tabBar, new Flexible(child: content)], | |
Hixie
2015/06/27 00:12:38
We don't usually bother type-annotating the childr
hansmuller
2015/06/29 16:49:41
OK. As you know, without the annotation code like
| |
353 direction: FlexDirection.vertical | |
354 ); | |
355 } | |
356 } | |
OLD | NEW |