I'm building a page with multiple styled sliders, so I made a separate SliderWidget class. The slider itself behaves normally, but when I try to print the value of the slider to console, it returns null as flutter: null
.
I've tried putting specific int values into my currentValue variable (in the SliderWidget class) to test with no luck, so I'm pretty sure that the problem is the getter itself, but I can't figure out what is wrong. I'm pretty new to flutter, so it's very possible I did something stupid.
Here is the slider object:
SliderWidget moodSlider = new SliderWidget(
sliderHeight: 48,
min: 0,
max: 10,
color1: 0xFF9BC1BC,
color2: 0xFF9BC1BC);
Here is the SliderWidget class:
import 'package:first_tutorial/MoodUpdate/custom_thumb_circle.dart';
import 'package:flutter/material.dart';
class SliderWidget extends StatefulWidget {
final double sliderHeight;
final int min;
final int max;
final fullWidth;
final int color1;
final int color2;
final int number;
SliderWidget(
{this.sliderHeight,
this.max,
this.min,
this.fullWidth = false,
this.color1,
this.color2,
this.number});
@override
_SliderWidgetState createState() => _SliderWidgetState();
}
class _SliderWidgetState extends State<SliderWidget> {
double currentValue = 0;
int get number => currentValue.round();
@override
Widget build(BuildContext context) {
double paddingFactor = .2;
if (this.widget.fullWidth) paddingFactor = .3;
return Container(
width: this.widget.fullWidth
? double.infinity
: (this.widget.sliderHeight) * 5.5,
height: (this.widget.sliderHeight),
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(
Radius.circular((this.widget.sliderHeight * .3)),
),
gradient: new LinearGradient(
colors: [
Color(this.widget.color1),
Color(this.widget.color2),
],
begin: const FractionalOffset(0.0, 0.0),
end: const FractionalOffset(1.0, 1.00),
stops: [0.0, 1.0],
tileMode: TileMode.clamp),
),
child: Padding(
padding: EdgeInsets.fromLTRB(this.widget.sliderHeight * paddingFactor,
2, this.widget.sliderHeight * paddingFactor, 2),
child: Row(
children: <Widget>[
Text(
'${this.widget.min}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: this.widget.sliderHeight * .3,
fontWeight: FontWeight.w700,
color: Colors.white,
),
),
SizedBox(
width: this.widget.sliderHeight * .1,
),
Expanded(
child: Center(
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: Colors.white.withOpacity(1),
inactiveTrackColor: Colors.white.withOpacity(.5),
trackHeight: 4.0,
thumbShape: CustomSliderThumbCircle(
thumbRadius: this.widget.sliderHeight * .4,
darkColor: this.widget.color1,
min: this.widget.min,
max: this.widget.max,
),
overlayColor: Colors.white.withOpacity(.4),
),
child: Slider(
value: currentValue,
onChanged: (value) {
setState(() {
currentValue = value;
});
}),
),
),
),
SizedBox(
width: this.widget.sliderHeight * .1,
),
Text(
'${this.widget.max}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: this.widget.sliderHeight * .3,
fontWeight: FontWeight.w700,
color: Colors.white,
),
),
],
),
),
);
}
}
Edit: I'm printing it to the console within this widget. It's at the bottom in the onPressed parameter:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Mood', style: TextStyle(fontFamily: 'WorkSans')),
backgroundColor: PrimaryColor,
),
backgroundColor: Color(0xFFF4F1BB),
body: Column(
children: <Widget>[
SizedBox(height: 20),
//Mood title
Align(
alignment: Alignment.center,
child: Text('How are you feeling?',
style: TextStyle(
color: Colors.grey[800],
fontSize: 20,
fontFamily: 'WorkSans'))),
SizedBox(height: 20),
//Mood slider
Align(
alignment: Alignment.center,
child:moodSlider),
SizedBox(height: 20),
//Sleep title
Align(
alignment: Alignment.center,
child: Text('How long did you sleep?',
style: TextStyle(
color: Colors.grey[800],
fontSize: 20,
fontFamily: 'WorkSans'))),
SizedBox(height: 20),
//Sleep slider
Align(
alignment: Alignment.center,
child: //SliderWidget(
// sliderHeight: 48,
// min: 0,
// max: 12,
// color1: 0xFF766E87,
// color2: 0xFF766E87)
sleepSlider),
SizedBox(height: 20),
//Save button
Align(
alignment: Alignment.bottomCenter,
child: RaisedButton(
child: Text('Save'),
textColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
color: PrimaryColor,
onPressed: () {
print(moodSlider.number);
}, //_save(moodValue, sleepValue),
)),
],
),
);
}
I see one getter named number
defined in your code..
int get number => currentValue.round();
..which is defined in _SliderWidgetState
class. Not in SliderWidget
class. These 2 are 2 different classes. So when you write moodSlider.number
, you are not calling the above getter. Because moodSlider
is an instance of SliderWidget
class and the getter is defined in the other class. Instead, by writing moodSlider.number
, what you are doing is - you are accessing the member variable number
of the SliderWidget
class..
class SliderWidget extends StatefulWidget {
final double sliderHeight;
final int min;
final int max;
final fullWidth;
final int color1;
final int color2;
final int number; //<-- this one here
SliderWidget(
{this.sliderHeight,
this.max,
this.min,
this.fullWidth = false,
this.color1,
this.color2,
this.number});
@override
_SliderWidgetState createState() => _SliderWidgetState();
}
..and this member variable number
is never assigned a value. That is why it always prints null
.
Edit:
For this to work, we can add an onChanged
callback to the SliderWidget
, just like the Slider
widget has. We can make this callback to accept a int
value parameter, so we can round it from inside _SliderWidgetState
and pass to the callback. I made a demo on dartpad. You can see it here - https://dartpad.dev/dc8fd327ff5b94edff6c6f6fe3fea17c