I'm using the Sleek_circular_Slider and was wondering if there is a way of changing the value/position of the slider from an external button press? I cant seem to see the value that it would be setting to change it.
Code:
Widget controlIndicator() {
return SleekCircularSlider(
min: 0,
max: 100,
initialValue: 4,
innerWidget: (value) {
return sliderCenterWidget();
},
appearance: CircularSliderAppearance(
spinnerMode: false,
animationEnabled: true,
size: 250,
customColors: CustomSliderColors(
dotColor: dark_grey,
shadowColor: dark_grey,
shadowMaxOpacity: 0.2,
shadowStep: 5,
progressBarColor: red,
trackColor: grey),
customWidths: CustomSliderWidths(
trackWidth: 7, progressBarWidth: 12, handlerSize: 8)),
onChange: (value) {
slider_value = value.round();
print(value);
});
}
did you try to set the initialValue as a variable? then change this var value on button press
Related
I need SfRangeSlider to display the tooltip below the slider instead of the top. As per here discussion here able to display the tooltip below the slider. It is displayed only when we change the slider. I need to display the tooltip below the slider all the time.
Widget _buildThumbIcon(TextEditingController controller) {
return Transform.translate(
// Here 20 is thumb diameter and 5 is spacing between thumb and text.
offset: const Offset(0, 25),
child: OverflowBox(
maxWidth: 150,
child: TextField(
textAlign: TextAlign.center,
decoration:
const InputDecoration(border: InputBorder.none, isDense: true),
controller: controller,
),
),
);
}
SfRangeSlider(
activeColor: primary,
inactiveColor: grey_e1,
min: 1.0,
max: 12.0,
showTicks: true,
showLabels: false,
stepSize: 1,
// interval: 1,
//minorTicksPerInterval: 1,
startThumbIcon: _buildThumbIcon(_rangeStartController),
endThumbIcon: _buildThumbIcon(_rangeEndController),
values: _values,
onChangeStart: (SfRangeValues newValues) {
_rangeStartController.text = _getFormattedText(newValues.start);
_rangeEndController.text = _getFormattedText(newValues.end);
},
onChanged: (SfRangeValues newValues) {
setState(() {
_rangeStartController.text = _getFormattedText(newValues.start);
_rangeEndController.text = _getFormattedText(newValues.end);
_values = newValues;
});
},
onChangeEnd: (SfRangeValues newValues) {
_rangeStartController.text = "";
_rangeEndController.text = "";
},
)
I'm implementing line chart in flutter i have draw the line chart but i need to show horizontal lines in different colors. Is there any way to get that?
Here is the attached image what i want to achieve.
LineChartData(
minX: 0,
maxX: 11,
minY: 0,
maxY: 6,
titlesData: LineTitles.getTitleData(),
gridData: FlGridData(
show: true,
getDrawingHorizontalLine: (value) {
return FlLine(
color: Colors.grey,
strokeWidth: 1,
);
},
drawVerticalLine: true,
getDrawingVerticalLine: (value) {
return FlLine(
color: Colors.grey,
strokeWidth: 1,
);
},
),
borderData: FlBorderData(
show: true,
border: Border.all(color: Colors.grey, width: 1),
),
lineBarsData: [
LineChartBarData(
spots: [
FlSpot(4.9, 5),
FlSpot(6.8, 2.5),
FlSpot(8, 4),
FlSpot(9.5, 3),
FlSpot(11, 4),
],
isCurved: true,
barWidth: 3,
),
],
),[![I need to show the orange and red horizontal lines][1]][1]
Yes you can check gridline colors in fl_chart. You've already used function with which you can modify these colors which is getDrawingHorizontalLine().
getDrawingHorizontalLine: (value) {
if(value == 1) {
return FlLine(
color: Colors.red,
strokeWidth: 2,
);
} else if (value == 2 ) {
return FlLine(
color: Colors.yellow,
strokeWidth: 2,
);
} else {
return FlLine(
color: Colors.grey,
strokeWidth: 2,
);
}
}
Now here as you can see I've added condition that if values are 1 or 2 then gridline colors should be red & yellow respectively. Now this is the ugly way to put condition to change color but you can do it dynamically yourself.
If you want to change vertical gridlines then you should use getDrawingVerticalLine() to change color values.
You can see my screenshot for output below.
This is my range slider widget implementation, I want to prevent the user from being able to slide the left thumb slider
RangeSlider(
divisions: 5,
activeColor: Colors.red[700],
inactiveColor: Colors.grey,
min: 1.0,
max: 10.0,
values: values,
labels: labels,
onChanged: (value) {
state(
() {
values = value;
labels = RangeLabels(
"${value.start.toInt().toString()}km",
"${value.end.toInt().toString()}km",
);
},
);
},
),
Add if (values.start != value.start) return; inside your onChanged, this will prevent updating values which prevent updating the RangeSlider
Comment from #ikerfah which helped was to include if(values.start != value.start) return; inside onChanged callback
RangeSlider(
divisions: 5,
activeColor: Colors.red[700],
inactiveColor: Colors.grey,
min: 1.0,
max: 10.0,
values: values,
labels: labels,
onChanged: (value) {
state(
() {
if (values.start != value.start) return;
values = value;
labels = RangeLabels(
"${value.start.toInt().toString()}km",
"${value.end.toInt().toString()}km",
);
},
);
},
),
flutter reduces padding SleekCircularSlider and text. It's sowing too much space between bar and text.
my code
SleekCircularSlider(
min: 0,
max: 120.0,
initialValue: 60,
appearance: CircularSliderAppearance(
startAngle: 110,
angleRange: 70,
animationEnabled: true,
infoProperties: InfoProperties(
bottomLabelText: 'kg',
bottomLabelStyle: TextStyle(
fontSize: 20,
),
mainLabelStyle: TextStyle(
fontSize: 25,
fontFamily: 'RalewaySemiBold',
),
modifier: (double value) {
final roundedValue = value.ceil().toInt().toString();
return '$roundedValue ';
},
),
customColors: CustomSliderColors(
hideShadow: true,
trackColor: Color(0xffCFE7FB),
dotColor: Color(0XFFFAFAFA),
progressBarColor: kPrimaryColor,
),
customWidths: CustomSliderWidths(
trackWidth: 4,
progressBarWidth: 12,
handlerSize: 3,
)
),
onChangeEnd: (double weight){
return weight;
},
),
Look like this
I need to reduce the gap between bar and text.
You can use the size parameter on the CircularSliderAppearance to control how much width and height is allotted to your SleekCircularSlider widget.
For example, I added,
appearance: CircularSliderAppearance(
size: 100, // Added this
startAngle: 110,
and the output is this,
Play around and check what size suits you best. :)
I have a slider that uses a value to render himself, it start rendering after I hit a button but the first time I render it, it gives me an error and then starts working properly.
This is the error:
The getter 'inSeconds' was called on null.
Receiver: null
Tried calling: inSeconds
This is the widget that uses the data:
child: Consumer<MyAudio>(
builder: (context, audioPlayer, child) =>
SleekCircularSlider(
appearance: CircularSliderAppearance(
customWidths: CustomSliderWidths(
progressBarWidth: 2.0,
trackWidth: 1.0,
handlerSize: 1.0,
shadowWidth: 1.0,
),
infoProperties: InfoProperties(
modifier: (value) => '',
),
customColors: CustomSliderColors(
trackColor: Colors.grey,
progressBarColor: Colors.black,
),
size: 4.0,
angleRange: 360,
startAngle: -90.0,
),
min: 0.0,
max: audioPlayer.songLength.inSeconds.toDouble(),
initialValue:
audioPlayer.position.inSeconds.toDouble(),
),
),
),
And this is the function that gives me the values songLength and position:
class MyAudio extends ChangeNotifier {
Duration songLength;
Duration position;
AudioPlayer _player = AudioPlayer();
AudioCache cache;
MyAudio() {
initAudio();
}
initAudio() {
cache = AudioCache(fixedPlayer: _player);
_player.onDurationChanged.listen((Duration d) {
songLength = d;
notifyListeners();
});
_player.onAudioPositionChanged.listen((Duration p) {
position = p;
notifyListeners();
});
I think I should use an async function, what do you think?
If you need more code here's my github repo with all the files: https://github.com/astroxd/sputofy_mobile/tree/main/sputofy_2
the slider is in /lib/miniPlayer and the values are in /lib/model/audioPlayer
The problem is that when the widget is built for first time, the audioPlayer.songLength and audioPlayer.position are null despite audioPlayer is non-null.
In this fragment of code you define a pair of listeners, but the callbacks are called after the first build.
_player.onDurationChanged.listen((Duration d) {
songLength = d;
notifyListeners();
});
_player.onAudioPositionChanged.listen((Duration p) {
position = p;
notifyListeners();
});
Then, a solution can be the following:
child: Consumer<MyAudio>(
builder: (context, audioPlayer, child) => SleekCircularSlider(
appearance: CircularSliderAppearance(
customWidths: CustomSliderWidths(
progressBarWidth: 2.0,
trackWidth: 1.0,
handlerSize: 1.0,
shadowWidth: 1.0,
),
infoProperties: InfoProperties(
modifier: (value) => '',
),
customColors: CustomSliderColors(
trackColor: Colors.grey,
progressBarColor: Colors.black,
),
size: 4.0,
angleRange: 360,
startAngle: -90.0,
),
min: 0.0,
max: audioPlayer.songLength?.inSeconds?.toDouble() ?? 0.0,
initialValue: audioPlayer.position?.inSeconds?.toDouble() ?? 0.0,
),
)
Or maybe use a loader instead.