Hello I try to refresh _currentValue
when I open a modal bottom sheet and I change the value from state full widget depense()
.
Here is my code
new RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 5,
highlightElevation: 10,
color: Colors.white,
splashColor: Colors.white,
child : new Text("${_currentValue}",textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.w400, fontSize: SizeConfig.safeBlockHorizontal! * 4)),
padding: const EdgeInsets.all (15.0),
onPressed: () {
setState(() {
showMaterialModalBottomSheet(isDismissible: true,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15)),
context: context,
builder: (context) => depense()
);
});
}),
class depense extends StatefulWidget {
const depense({Key? key}) : super(key: key);
@override
State<depense> createState() => _depenseState();
}
class _depenseState extends State<depense> {
int _currentValue = 5;
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width/1,
height: MediaQuery.of(context).size.height/1.8,
child :
Padding(
padding: const EdgeInsets.only(left:20,right:20),
child:
Container(
alignment: Alignment.center,
child: NumberPicker(
axis: Axis.horizontal,
itemHeight: 70,
itemWidth: 70,
step: 1,
selectedTextStyle: const TextStyle(
fontSize: 30.0,
color: Color(0xff61d3cb),
fontWeight: FontWeight.w800,
),
textStyle: const TextStyle(
color: Colors.black,
fontSize: 12.0,
),
value: _currentValue,
minValue: 0,
maxValue: 1000,
onChanged: (v) {
setState(() {
_currentValue = v;
});
},
),
),
));
}
}
If I add the widget build from depense state full widget directly on the modalbottomsheet like bellow, Text("${_currentValue}"
is upgrade but NumberPicker return to initial value...
But when I create the statefull widget I can use NumberPicker but not refresh data...
new RaisedButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
elevation: 5,
highlightElevation: 10,
color: Colors.white,
splashColor: Colors.white,
child : new Text("${_currentValue}",textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.w400, fontSize: SizeConfig.safeBlockHorizontal! * 4)),
padding: const EdgeInsets.all (15.0),
onPressed: () {
setState(() {
showMaterialModalBottomSheet(isDismissible: true,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15)),
context: context,
builder: (context) => Container(
width: MediaQuery.of(context).size.width/1,
height: MediaQuery.of(context).size.height/1.8,
child :
Padding(
padding: const EdgeInsets.only(left:20,right:20),
child:
Container(
alignment: Alignment.center,
child: NumberPicker(
axis: Axis.horizontal,
itemHeight: 70,
itemWidth: 70,
step: 1,
selectedTextStyle: const TextStyle(
fontSize: 30.0,
color: Color(0xff61d3cb),
fontWeight: FontWeight.w800,
),
textStyle: const TextStyle(
color: Colors.black,
fontSize: 12.0,
),
value: _currentValue,
minValue: 0,
maxValue: 1000,
onChanged: (v) {
setState(() {
_currentValue = v;
});
},
),
),
))
);
});
}),
CodePudding user response:
You need define currentValue
in your main class and pass a function to depense
class like this:
class depense extends StatefulWidget {
final Function(int) onChange; //<-- add this
const depense({Key? key, required this.onChange}) : super(key: key);
@override
State<depense> createState() => _depenseState();
}
class _depenseState extends State<depense> {
int _currentValue = 5;
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width / 1,
height: MediaQuery.of(context).size.height / 1.8,
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: Container(
alignment: Alignment.center,
child: NumberPicker(
axis: Axis.horizontal,
itemHeight: 70,
itemWidth: 70,
step: 1,
selectedTextStyle: const TextStyle(
fontSize: 30.0,
color: Color(0xff61d3cb),
fontWeight: FontWeight.w800,
),
textStyle: const TextStyle(
color: Colors.black,
fontSize: 12.0,
),
value: _currentValue,
minValue: 0,
maxValue: 1000,
onChanged: (v) {
widget.onChange(v);
setState(() {
_currentValue = v;
});
},
),
),
));
}
}
Then you use it like this:
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
elevation: 5,
highlightElevation: 10,
color: Colors.white,
splashColor: Colors.white,
child: new Text("${_currentValue}",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: SizeConfig.safeBlockHorizontal! * 4)),
padding: const EdgeInsets.all(15.0),
onPressed: () {
setState(() {
showMaterialModalBottomSheet(
isDismissible: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
context: context,
builder: (context) => depense(onChange:(value){
setState(() {
_currentValue = value;
});
}));
});
})
CodePudding user response:
It looks like _currentValue is a local state variable of the dispense class and you have another variable by same name in parent class also. Changes in local state variables are not reflected in parent widgets.
Usually, you should use any state management libraries in such scenarios, but a simple solution can be to pass a callback function from RaisedButton to dispense widget which will return its value.
class depense extends StatefulWidget {
Function changeCurrentValue(int val);
const depense({Key? key}) : super(key: key);
@override
State<depense> createState() => _depenseState();
}
class _depenseState extends State<depense> {
...
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width/1,
height: MediaQuery.of(context).size.height/1.8,
child :
...
onChanged: (v) {
widget.changeCurrentValue(v);
}
In RaisedButton
int _currentValue = 5;
void changeCurrentValue(int v){
setState(() {
_currentValue = v;
})
}
new RaisedButton(
...
showMaterialModalBottomSheet(isDismissible: true,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15)),
context: context,
builder: (context) => depense(changeCurrentValue: changeCurrentValue)
....