| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/material.dart'; |
| import '../../gallery_localizations.dart'; |
| import 'material_demo_types.dart'; |
| |
| class TabsDemo extends StatelessWidget { |
| const TabsDemo({super.key, required this.type}); |
| |
| final TabsDemoType type; |
| |
| @override |
| Widget build(BuildContext context) { |
| Widget tabs; |
| switch (type) { |
| case TabsDemoType.scrollable: |
| tabs = _TabsScrollableDemo(); |
| case TabsDemoType.nonScrollable: |
| tabs = _TabsNonScrollableDemo(); |
| } |
| return tabs; |
| } |
| } |
| |
| // BEGIN tabsScrollableDemo |
| |
| class _TabsScrollableDemo extends StatefulWidget { |
| @override |
| __TabsScrollableDemoState createState() => __TabsScrollableDemoState(); |
| } |
| |
| class __TabsScrollableDemoState extends State<_TabsScrollableDemo> |
| with SingleTickerProviderStateMixin, RestorationMixin { |
| TabController? _tabController; |
| |
| final RestorableInt tabIndex = RestorableInt(0); |
| |
| @override |
| String get restorationId => 'tab_scrollable_demo'; |
| |
| @override |
| void restoreState(RestorationBucket? oldBucket, bool initialRestore) { |
| registerForRestoration(tabIndex, 'tab_index'); |
| _tabController!.index = tabIndex.value; |
| } |
| |
| @override |
| void initState() { |
| _tabController = TabController( |
| length: 12, |
| vsync: this, |
| ); |
| _tabController!.addListener(() { |
| // When the tab controller's value is updated, make sure to update the |
| // tab index value, which is state restorable. |
| setState(() { |
| tabIndex.value = _tabController!.index; |
| }); |
| }); |
| super.initState(); |
| } |
| |
| @override |
| void dispose() { |
| _tabController!.dispose(); |
| tabIndex.dispose(); |
| super.dispose(); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| final GalleryLocalizations localizations = GalleryLocalizations.of(context)!; |
| final List<String> tabs = <String>[ |
| localizations.colorsRed, |
| localizations.colorsOrange, |
| localizations.colorsGreen, |
| localizations.colorsBlue, |
| localizations.colorsIndigo, |
| localizations.colorsPurple, |
| localizations.colorsRed, |
| localizations.colorsOrange, |
| localizations.colorsGreen, |
| localizations.colorsBlue, |
| localizations.colorsIndigo, |
| localizations.colorsPurple, |
| ]; |
| |
| return Scaffold( |
| appBar: AppBar( |
| automaticallyImplyLeading: false, |
| title: Text(localizations.demoTabsScrollingTitle), |
| bottom: TabBar( |
| controller: _tabController, |
| isScrollable: true, |
| tabs: <Widget>[ |
| for (final String tab in tabs) Tab(text: tab), |
| ], |
| ), |
| ), |
| body: TabBarView( |
| controller: _tabController, |
| children: <Widget>[ |
| for (final String tab in tabs) |
| Center( |
| child: Text(tab), |
| ), |
| ], |
| ), |
| ); |
| } |
| } |
| |
| // END |
| |
| // BEGIN tabsNonScrollableDemo |
| |
| class _TabsNonScrollableDemo extends StatefulWidget { |
| @override |
| __TabsNonScrollableDemoState createState() => __TabsNonScrollableDemoState(); |
| } |
| |
| class __TabsNonScrollableDemoState extends State<_TabsNonScrollableDemo> |
| with SingleTickerProviderStateMixin, RestorationMixin { |
| late TabController _tabController; |
| |
| final RestorableInt tabIndex = RestorableInt(0); |
| |
| @override |
| String get restorationId => 'tab_non_scrollable_demo'; |
| |
| @override |
| void restoreState(RestorationBucket? oldBucket, bool initialRestore) { |
| registerForRestoration(tabIndex, 'tab_index'); |
| _tabController.index = tabIndex.value; |
| } |
| |
| @override |
| void initState() { |
| super.initState(); |
| _tabController = TabController( |
| length: 3, |
| vsync: this, |
| ); |
| _tabController.addListener(() { |
| // When the tab controller's value is updated, make sure to update the |
| // tab index value, which is state restorable. |
| setState(() { |
| tabIndex.value = _tabController.index; |
| }); |
| }); |
| } |
| |
| @override |
| void dispose() { |
| _tabController.dispose(); |
| tabIndex.dispose(); |
| super.dispose(); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| final GalleryLocalizations localizations = GalleryLocalizations.of(context)!; |
| final List<String> tabs = <String>[ |
| localizations.colorsRed, |
| localizations.colorsOrange, |
| localizations.colorsGreen, |
| ]; |
| |
| return Scaffold( |
| appBar: AppBar( |
| automaticallyImplyLeading: false, |
| title: Text( |
| localizations.demoTabsNonScrollingTitle, |
| ), |
| bottom: TabBar( |
| controller: _tabController, |
| tabs: <Widget>[ |
| for (final String tab in tabs) Tab(text: tab), |
| ], |
| ), |
| ), |
| body: TabBarView( |
| controller: _tabController, |
| children: <Widget>[ |
| for (final String tab in tabs) |
| Center( |
| child: Text(tab), |
| ), |
| ], |
| ), |
| ); |
| } |
| } |
| |
| // END |