Created
June 18, 2019 23:06
-
-
Save shihaohong/b5723a5902c6549cddbf6f1908255b83 to your computer and use it in GitHub Desktop.
throws exception when adding/removing tabs mid-animation
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
// Flutter code sample for material.TabController.2 | |
// A sample application dynamically adds and removes tabs. | |
import 'dart:math' as math; | |
import 'package:flutter/material.dart'; | |
void main() => runApp(MyApp()); | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
home: MyTabbedPage(title: 'Dynamic tabs demo'), | |
); | |
} | |
} | |
class MyTabbedPage extends StatefulWidget { | |
MyTabbedPage({Key key, this.title}) : super(key: key); | |
final String title; | |
@override | |
_MyTabbedPageState createState() => _MyTabbedPageState(); | |
} | |
class _MyTabbedPageState extends State<MyTabbedPage> | |
with TickerProviderStateMixin { | |
List<Tab> myTabs = <Tab>[ | |
Tab(text: '1'), | |
Tab(text: '2'), | |
]; | |
TabController _tabController; | |
@override | |
void initState() { | |
super.initState(); | |
_tabController = TabController(vsync: this, length: myTabs.length); | |
} | |
@override | |
void dispose() { | |
_tabController.dispose(); | |
super.dispose(); | |
} | |
void _updateTabController() { | |
int newIndex; | |
if (_tabController.index >= myTabs.length) { | |
newIndex = math.max(0, myTabs.length - 2); | |
} else { | |
newIndex = _tabController.index; | |
} | |
_tabController.dispose(); | |
_tabController = TabController( | |
vsync: this, | |
length: myTabs.length, | |
initialIndex: newIndex, | |
); | |
} | |
void _addNewTab() { | |
setState(() { | |
myTabs = myTabs.toList() | |
..add(Tab(text: '${myTabs.length + 1}')); | |
_updateTabController(); | |
}); | |
setState((){}); | |
} | |
void _removeLastTab() { | |
setState(() { | |
myTabs = myTabs.toList() | |
..removeLast(); | |
_updateTabController(); | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
actions: [ | |
IconButton( | |
icon: Icon(Icons.remove), | |
onPressed: _removeLastTab, | |
), | |
], | |
bottom: TabBar( | |
controller: _tabController, | |
tabs: myTabs, | |
), | |
), | |
body: TabBarView( | |
controller: _tabController, | |
children: myTabs.map((Tab tab) { | |
final String label = tab.text.toLowerCase(); | |
return Center( | |
child: Text( | |
'This is the tab $label', | |
style: const TextStyle(fontSize: 36), | |
), | |
); | |
}).toList(), | |
), | |
floatingActionButton: FloatingActionButton( | |
onPressed: _addNewTab, | |
child: Icon(Icons.add), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment