Reputation: 311
How do I add tabs dynamically to the TabBar Widget in Flutter? The list of tabs is fetched from the internet using a REST API.
When I fetch the list using the code below I get the following errors:
RangeError (index): Invalid value: Only valid value is 0: 1
A RenderFlex overflowed by 99896 pixels on the bottom.
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Future<List<Categories>> categoriesList;
final categoryTabs = <Tab>[
Tab(text: 'Home'),
];
@override
void initState() {
super.initState();
categoriesList = NewsServices.fetchCategoriesList(lang: 'en');
categoriesList.then((categories) {
categories.forEach((category) {
setState(() {
categoryTabs.add(Tab(
text: category.name,
));
});
});
});
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: categoryTabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('Example App'),
bottom: TabBar(
isScrollable: true,
tabs: categoryTabs,
),
),
body: SafeArea(...),
),
),
);
}
Upvotes: 1
Views: 2196
Reputation: 627
You have to iterate the list which you achieved from the REST API.
Suppose, we declare a list of String which you will get from the REST API.
List<String> tabTextList;
Then declare the list of tabs.
List<Tab> _tabs = List<Tab>();
Then iterate the list of strings.
List<Tab> getTabs() {
_tabs.clear();
for (int i = 0; i < tabTextList.length; i++) {
_tabs.add(getTab(i));
}
return _tabs;
}
Tab getTab(int widgetNumber) {
return Tab(
text: "${tabTextList[widgetNumber]}",
);
}
Then the build function will be like this.
@override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: tabTextList.length,
child: Scaffold(
bottom: TabBar(
isScrollable: true,
tabs: getTabs(),
),
),
body: Container(),
),
),
);
}
According to your updated code you have to change some portion.
Use another variable categoryTabsTemp to store the array temporarily. After that you have to use setState to update the categoryTabs and rebuild. The updated code should be like that.
var categoryTabs = <Tab>[
Tab(text: 'Home'),
];
var categoryTabsTemp = <Tab>[
Tab(text: 'Home'),
];
@override
void initState() {
super.initState();
categoriesList = NewsServices.fetchCategoriesList(lang: 'en');
categoriesList.then((categories) {
categories.forEach((category) {
categoryTabsTemp.add(Tab(
text: category.name,
));
});
setState(() {
categoryTabs = categoryTabsTemp;
});
});
}
Upvotes: 4