Reputation: 1671
I have created a Custom Segments widget which creates Multiple TABS according to List. I am updating selectionsList
from homepage.dart
but still, my segments are not updating runtime according to changed selectionsList
Segments.dart (Custom SegmentWidget which creates Cupertino tabs)
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SegmentsWidget extends StatefulWidget {
@override
_SegmentsWidgetState createState() => _SegmentsWidgetState();
final List selectionsList;
final ValueChanged<int> onSelectTab;
final VoidCallback onTap;
final int selectedValue;
SegmentsWidget(
{this.selectionsList, this.onSelectTab, this.onTap, this.selectedValue});
}
class _SegmentsWidgetState extends State<SegmentsWidget> {
Map<int, Widget> tabWidget = Map<int, Widget>();
int selectedTab = 0;
@override
void initState() {
super.initState();
print("INit State ${widget.selectionsList}");
setState(() {
widget.selectionsList.asMap().forEach((index, value) {
tabWidget.addAll({
index: Container(
height: 40,
child: Center(
child: Text(
widget.selectionsList[index],
style: TextStyle(fontFamily: 'Exo2', fontSize: 12.0),
),
))
});
});
});
}
@override
void didUpdateWidget(SegmentsWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("Did update");
}
@override
Widget build(BuildContext context) {
return Container(
child: Row(
children: <Widget>[
Expanded(
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: CupertinoSegmentedControl<int>(
padding: EdgeInsets.symmetric(vertical: 8),
children: tabWidget,
onValueChanged: (int index) {
setState(() {
selectedTab = index;
});
widget.onSelectTab(index);
},
groupValue: widget.selectedValue ?? selectedTab,
),
),
)
],
),
);
}
}
HomePage.dart
From Home Page, I am updating selection array but still my segments are not updating according to selectionList.
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<String> selection;
int selectedTab = -1;
@override
void initState() {
super.initState();
selection = ["A", "B"];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Dynamic Segments")),
body: Container(
child: Column(
children: <Widget>[
SegmentsWidget(
selectionsList: selection,
onSelectTab: (selectTab) {
setState(() {
selectedTab = selectTab;
});
},
),
RaisedButton(child: Text("AB"),onPressed: (){
setState(() {
selection = ["A", "B"];
});
}),
RaisedButton(child: Text("ABC"),onPressed: (){
setState(() {
selection = ["A", "B", "C"];
});
}),
RaisedButton(child: Text("ABCD"),onPressed: (){
setState(() {
selection = ["A", "B", "C","D"];
});
})
],
),
),
);
}
}
I assume that initState of Segment Widget called once only. I even tried in didUpdateWidget but still not getting updated tabs.
Issue: How to update tabWidgets which is mentioned in my custom widget from another stateful widget?
Upvotes: 1
Views: 1399
Reputation: 630
I change some parts of code. Instead of calling your code (that need to be called again on setState) in initState() function, call your code inside the widget with your own method.
see getTabChilds()
function below of code.
class _SegmentsWidgetState extends State<SegmentsWidget> {
Map<int, Widget> tabWidget = Map<int, Widget>();
int selectedTab = 0;
@override
void initState() {
super.initState();
print("INit State ${widget.selectionsList}");
}
@override
void didUpdateWidget(SegmentsWidget oldWidget) {
super.didUpdateWidget(oldWidget);
print("Did update");
}
@override
Widget build(BuildContext context) {
return Container(
child: Row(
children: <Widget>[
Expanded(
child: SizedBox(
width: MediaQuery.of(context).size.width,
child: CupertinoSegmentedControl<int>(
padding: EdgeInsets.symmetric(vertical: 8),
children: getTabChilds(),
onValueChanged: (int index) {
setState(() {
selectedTab = index;
});
widget.onSelectTab(index);
},
groupValue: widget.selectedValue ?? selectedTab,
),
),
)
],
),
);
}
Map<int, Widget> getTabChilds() {
tabWidget = Map<int, Widget>();
widget.selectionsList.asMap().forEach((index, value) {
tabWidget.addAll({
index: Container(
height: 40,
child: Center(
child: Text(
widget.selectionsList[index],
style: TextStyle(fontFamily: 'Exo2', fontSize: 12.0),
),
))
});
});
return tabWidget;
}
}
It's tested and works fine.
Upvotes: 2