Flutter - How to correctly delete a tab in a TabBarView
I'm using TabBarView to create a browser-like multi-tab application with dynamic tab creation. I've been following this answer. However I run into a quite bizzare problem when trying to delete a tab. Since I'm a beginner, I'm not sure if I did the wrong way or it is a Flutter bug.
Overview of this problem: If there remains two tabs in TabBarView, and you deleted the second tab while you are viewing it, TabBarView throws a exception, complaining that it can not perform scroll animation when item number < 2. However, this exception keeps coming up even if I switched tab in advance in the function. And this exception screws tab management from that point on.
I'd really appreciate if someone can show me the correct way of implementing a dynamic tab system.
The demo code is as follows. The code is complete and ready to run. Create a few tabs, then delete them from back to front. An exception will occur when you delete the second last tab. After that the tab system will behave like a mess.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> with TickerProviderStateMixin {
List<Tab> tabs = ;TabController tabController;var count = 1;
void newTab() {
setState(() {
tabs.add(Tab(text: '$count',));count++;
tabController = TabController(length: tabs.length, vsync: this);
});
}
void closeCurrentTab() {
setState(() {
// A bunch of if-statement..........
// Even if you switch the tab before deletion, the error still occur.
//tabController.animateTo(tabController.index-1);
tabs.removeAt(tabController.index);
tabController = TabController(length: tabs.length, vsync: this);
});
}
@override void initState() {
super.initState();
tabs.add(Tab(text: '0',));
tabController = TabController(length: tabs.length, vsync: this);
}
@override void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.add), onPressed: newTab),
IconButton(icon: Icon(Icons.close), onPressed: closeCurrentTab,)
],
bottom: TabBar(controller: tabController, tabs: tabs.map((tab) => tab).toList()),// A trick to trigger TabBar rebuild.
),
body: TabBarView(controller: tabController, children: tabs.map((tab) => Text(tab.text)).toList()),
),
);
}
}
It appears to me that the scroll animation after deletion is performed regardless of TabController.animateTo().
tabs widget

add a comment |
I'm using TabBarView to create a browser-like multi-tab application with dynamic tab creation. I've been following this answer. However I run into a quite bizzare problem when trying to delete a tab. Since I'm a beginner, I'm not sure if I did the wrong way or it is a Flutter bug.
Overview of this problem: If there remains two tabs in TabBarView, and you deleted the second tab while you are viewing it, TabBarView throws a exception, complaining that it can not perform scroll animation when item number < 2. However, this exception keeps coming up even if I switched tab in advance in the function. And this exception screws tab management from that point on.
I'd really appreciate if someone can show me the correct way of implementing a dynamic tab system.
The demo code is as follows. The code is complete and ready to run. Create a few tabs, then delete them from back to front. An exception will occur when you delete the second last tab. After that the tab system will behave like a mess.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> with TickerProviderStateMixin {
List<Tab> tabs = ;TabController tabController;var count = 1;
void newTab() {
setState(() {
tabs.add(Tab(text: '$count',));count++;
tabController = TabController(length: tabs.length, vsync: this);
});
}
void closeCurrentTab() {
setState(() {
// A bunch of if-statement..........
// Even if you switch the tab before deletion, the error still occur.
//tabController.animateTo(tabController.index-1);
tabs.removeAt(tabController.index);
tabController = TabController(length: tabs.length, vsync: this);
});
}
@override void initState() {
super.initState();
tabs.add(Tab(text: '0',));
tabController = TabController(length: tabs.length, vsync: this);
}
@override void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.add), onPressed: newTab),
IconButton(icon: Icon(Icons.close), onPressed: closeCurrentTab,)
],
bottom: TabBar(controller: tabController, tabs: tabs.map((tab) => tab).toList()),// A trick to trigger TabBar rebuild.
),
body: TabBarView(controller: tabController, children: tabs.map((tab) => Text(tab.text)).toList()),
),
);
}
}
It appears to me that the scroll animation after deletion is performed regardless of TabController.animateTo().
tabs widget

Well, since there is currently no answer, I'm sharing my workaround. Customizing PageView instead of using TabBarView solved this problem. A great example to follow is package:simple_coverflow.
– First_Strike
Nov 17 '18 at 3:55
add a comment |
I'm using TabBarView to create a browser-like multi-tab application with dynamic tab creation. I've been following this answer. However I run into a quite bizzare problem when trying to delete a tab. Since I'm a beginner, I'm not sure if I did the wrong way or it is a Flutter bug.
Overview of this problem: If there remains two tabs in TabBarView, and you deleted the second tab while you are viewing it, TabBarView throws a exception, complaining that it can not perform scroll animation when item number < 2. However, this exception keeps coming up even if I switched tab in advance in the function. And this exception screws tab management from that point on.
I'd really appreciate if someone can show me the correct way of implementing a dynamic tab system.
The demo code is as follows. The code is complete and ready to run. Create a few tabs, then delete them from back to front. An exception will occur when you delete the second last tab. After that the tab system will behave like a mess.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> with TickerProviderStateMixin {
List<Tab> tabs = ;TabController tabController;var count = 1;
void newTab() {
setState(() {
tabs.add(Tab(text: '$count',));count++;
tabController = TabController(length: tabs.length, vsync: this);
});
}
void closeCurrentTab() {
setState(() {
// A bunch of if-statement..........
// Even if you switch the tab before deletion, the error still occur.
//tabController.animateTo(tabController.index-1);
tabs.removeAt(tabController.index);
tabController = TabController(length: tabs.length, vsync: this);
});
}
@override void initState() {
super.initState();
tabs.add(Tab(text: '0',));
tabController = TabController(length: tabs.length, vsync: this);
}
@override void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.add), onPressed: newTab),
IconButton(icon: Icon(Icons.close), onPressed: closeCurrentTab,)
],
bottom: TabBar(controller: tabController, tabs: tabs.map((tab) => tab).toList()),// A trick to trigger TabBar rebuild.
),
body: TabBarView(controller: tabController, children: tabs.map((tab) => Text(tab.text)).toList()),
),
);
}
}
It appears to me that the scroll animation after deletion is performed regardless of TabController.animateTo().
tabs widget

I'm using TabBarView to create a browser-like multi-tab application with dynamic tab creation. I've been following this answer. However I run into a quite bizzare problem when trying to delete a tab. Since I'm a beginner, I'm not sure if I did the wrong way or it is a Flutter bug.
Overview of this problem: If there remains two tabs in TabBarView, and you deleted the second tab while you are viewing it, TabBarView throws a exception, complaining that it can not perform scroll animation when item number < 2. However, this exception keeps coming up even if I switched tab in advance in the function. And this exception screws tab management from that point on.
I'd really appreciate if someone can show me the correct way of implementing a dynamic tab system.
The demo code is as follows. The code is complete and ready to run. Create a few tabs, then delete them from back to front. An exception will occur when you delete the second last tab. After that the tab system will behave like a mess.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> with TickerProviderStateMixin {
List<Tab> tabs = ;TabController tabController;var count = 1;
void newTab() {
setState(() {
tabs.add(Tab(text: '$count',));count++;
tabController = TabController(length: tabs.length, vsync: this);
});
}
void closeCurrentTab() {
setState(() {
// A bunch of if-statement..........
// Even if you switch the tab before deletion, the error still occur.
//tabController.animateTo(tabController.index-1);
tabs.removeAt(tabController.index);
tabController = TabController(length: tabs.length, vsync: this);
});
}
@override void initState() {
super.initState();
tabs.add(Tab(text: '0',));
tabController = TabController(length: tabs.length, vsync: this);
}
@override void dispose() {
tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(icon: Icon(Icons.add), onPressed: newTab),
IconButton(icon: Icon(Icons.close), onPressed: closeCurrentTab,)
],
bottom: TabBar(controller: tabController, tabs: tabs.map((tab) => tab).toList()),// A trick to trigger TabBar rebuild.
),
body: TabBarView(controller: tabController, children: tabs.map((tab) => Text(tab.text)).toList()),
),
);
}
}
It appears to me that the scroll animation after deletion is performed regardless of TabController.animateTo().
tabs widget

tabs widget

asked Nov 15 '18 at 13:07


First_Strike
1128
1128
Well, since there is currently no answer, I'm sharing my workaround. Customizing PageView instead of using TabBarView solved this problem. A great example to follow is package:simple_coverflow.
– First_Strike
Nov 17 '18 at 3:55
add a comment |
Well, since there is currently no answer, I'm sharing my workaround. Customizing PageView instead of using TabBarView solved this problem. A great example to follow is package:simple_coverflow.
– First_Strike
Nov 17 '18 at 3:55
Well, since there is currently no answer, I'm sharing my workaround. Customizing PageView instead of using TabBarView solved this problem. A great example to follow is package:simple_coverflow.
– First_Strike
Nov 17 '18 at 3:55
Well, since there is currently no answer, I'm sharing my workaround. Customizing PageView instead of using TabBarView solved this problem. A great example to follow is package:simple_coverflow.
– First_Strike
Nov 17 '18 at 3:55
add a comment |
1 Answer
1
active
oldest
votes
Well it turns out to be a flutter widget bug. It should not throw this exception when deleting tabs.
As reported in this Github issue. It should be fixed sometime in the future.
Right now I'm using PageView as an alternative. PageView works just fine.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53320186%2fflutter-how-to-correctly-delete-a-tab-in-a-tabbarview%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Well it turns out to be a flutter widget bug. It should not throw this exception when deleting tabs.
As reported in this Github issue. It should be fixed sometime in the future.
Right now I'm using PageView as an alternative. PageView works just fine.
add a comment |
Well it turns out to be a flutter widget bug. It should not throw this exception when deleting tabs.
As reported in this Github issue. It should be fixed sometime in the future.
Right now I'm using PageView as an alternative. PageView works just fine.
add a comment |
Well it turns out to be a flutter widget bug. It should not throw this exception when deleting tabs.
As reported in this Github issue. It should be fixed sometime in the future.
Right now I'm using PageView as an alternative. PageView works just fine.
Well it turns out to be a flutter widget bug. It should not throw this exception when deleting tabs.
As reported in this Github issue. It should be fixed sometime in the future.
Right now I'm using PageView as an alternative. PageView works just fine.
answered Nov 19 '18 at 15:40


First_Strike
1128
1128
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53320186%2fflutter-how-to-correctly-delete-a-tab-in-a-tabbarview%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Well, since there is currently no answer, I'm sharing my workaround. Customizing PageView instead of using TabBarView solved this problem. A great example to follow is package:simple_coverflow.
– First_Strike
Nov 17 '18 at 3:55