matthewfx / sleek_circular_slider Goto Github PK
View Code? Open in Web Editor NEWSleek circular slider for Flutter
License: MIT License
Sleek circular slider for Flutter
License: MIT License
I'm trying to run the example project and I'm getting this error:
══╡ EXCEPTION CAUGHT BY SCHEDULER LIBRARY ╞═════════════════════════════════════════════════════════
The following UnimplementedError was thrown during a scheduler callback:
UnimplementedError
When the exception was thrown, this was the stack:
package:dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 196:49 throw_
package:build_web_compilers/lib/_engine/engine/shader.dart 51:5 createPaintStyle
package:build_web_compilers/lib/_engine/engine/bitmap_canvas.dart 212:23 [_applyPaint]
package:build_web_compilers/lib/_engine/engine/bitmap_canvas.dart 343:5 drawPath
package:build_web_compilers/lib/_engine/engine/surface/recording_canvas.dart 990:11 apply
package:build_web_compilers/lib/_engine/engine/surface/recording_canvas.dart 78:18 apply
package:build_web_compilers/lib/_engine/engine/surface/picture.dart 253:35 paintCallback
package:build_web_compilers/lib/_engine/engine/surface/surface.dart 71:14 commitScene
package:build_web_compilers/lib/_engine/engine/surface/scene_builder.dart 520:5 build
package:flutter/src/rendering/layer.dart 801:35 buildScene
package:flutter/src/rendering/view.dart 230:36 compositeFrame
package:flutter/src/rendering/binding.dart 405:18 drawFrame
package:flutter/src/widgets/binding.dart 797:13 drawFrame
package:flutter/src/rendering/binding.dart 283:5 [_handlePersistentFrameCallback]
package:flutter/src/scheduler/binding.dart 1109:15 [_invokeFrameCallback]
package:flutter/src/scheduler/binding.dart 1048:9 handleDrawFrame
package:flutter/src/scheduler/binding.dart 857:7 <fn>
package:dart-sdk/lib/_internal/js_dev_runtime/private/isolate_helper.dart 50:19 internalCallback
════════════════════════════════════════════════════════════════════════════════════════════════════
Another exception was thrown: NoSuchMethodError: invalid member on null: 'doesFitBounds'
Another exception was thrown: Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/surface/scene_builder.dart:267:12
Another exception was thrown: Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/surface/scene_builder.dart:267:12
Another exception was thrown: Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/surface/scene_builder.dart:267:12
Another exception was thrown: Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/surface/scene_builder.dart:267:12
my flutter doctor:
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v1.14.6, on Mac OS X 10.15.3 19D76, locale es-419)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 3.5)
[✓] VS Code (version 1.43.0)
[✓] Connected device (2 available)
• No issues found!
I'm not sure if this is intended or not, but when I tap on the circle where no track is drawn I expect it to be ignored. Is this intended, a bug, or am I doing something wrong?
This is my code.
SleekCircularSlider(
appearance: CircularSliderAppearance(
animationEnabled: false,
size: 300,
customWidths: CustomSliderWidths(
handlerSize: 20,
trackWidth: 10,
shadowWidth: 0,
progressBarWidth: 10,
),
customColors: CustomSliderColors(
dotColor: Theme.of(context).accentColor,
trackColor: Theme.of(context).disabledColor,
progressBarColors: temperatureGradient.colors.reversed
.toList(),
),
),
innerWidget: (sliderValue) => SliderInnerWidget(sliderValue),
min: 8,
max: 28,
initialValue: climateControllerHelper.setpoint,
onChange: (v) {
LOG.info("Change: $v");
},
onChangeStart: (v) {
LOG.info("Start: $v");
},
onChangeEnd: (double value) {
doThings(value);
},
)
in my case I have a music player and I need the currently value of slider , update based on the music position .
I want value
parameter like default flutter slider.
found a bug when min equals max the method of
double valueToPercentage(double value, double min, double max) { return value / ((max - min) / 100); }
in utils.dart return NaN
because of division by zero.
as a workaround, I'm checking when min==max and setting max=min+0.1
The following assertion was thrown building PlayOutPlayer(dirty, dependencies: [MediaQuery], state: _PlayOutPlayer#f3517):
'package:sleek_circular_slider/src/circular_slider.dart': Failed assertion: line 45 pos 16: 'min <= max': is not true.
Hi there!
Amazing work on the lib!
I would love to see the option to have the slider move in steps rather than continuously. For instance, if the user is only allowed to select values multiple of 5 (5, 10, 15..). We can set the main label to only display such values
((v / 5).round() * 5).toString()
however, there's no way of making the slider itself skip/jump in increments of 5.
After setting initial value ,min and max dynamically the slider doesnt reset to intitial value .It show same position of slider ,though min, max change are working
It would be great if you could add a gradient for the track!
Either use the progressBarColors
when trackColor
is null
.
Or something like this in _CurvePainter
by adding trackColors
:
final progressBarRect = Rect.fromLTWH(0.0, 0.0, size.width, size.width);
Paint trackPaint;
if (appearance.trackColors != null){
final trackGradient = SweepGradient(
startAngle: degreeToRadians(appearance.gradientStartAngle),
endAngle: degreeToRadians(appearance.gradientStopAngle),
tileMode: TileMode.mirror,
colors: appearance.trackColors,
);
trackPaint = Paint()
..shader = trackGradient.createShader(progressBarRect)
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = appearance.trackWidth;
} else {
trackPaint = Paint()
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = appearance.trackWidth
..color = appearance.trackColor;
}
drawCircularArc(
canvas: canvas,
size: size,
paint: trackPaint,
ignoreAngle: true,
spinnerMode: appearance.spinnerMode);
It would be extremely useful to have a possibility to disable handling taps on Track. So the user will be able to change slider position only by dragging the Dot.
The use case:
I have several sliders inside a ListView and it is impossible to scroll ListView tapping anywhere around the slider.
Is it possible to continue sliding it around and around?
Sry, i found the answer to my simple problem, and if you see this message is that i didn't find how to delete it :).
Thanks for this amazing package anyways !
First of all, great work on this lib! I love how beautiful and customizable it is!
I ran into a scenario where the initialvalue
field was updated with a value greater than the max
.
Imagine if someone set a number of calories, but managed to pass that number. It would be nice if we could represent that, maybe with a separated slider color as well to represent that the max
value was overpassed.
Keep up the great work!
Thanks for this widget,it is really awesome and customizable, but i am wondering if i want to set a value dynamically how would i do it? well, i can set the initial value and i can update it, but if i want to use both user interaction change and dynamic value change i can't do it, if you can add where i can know if the value change is coming from the user interaction or not, it could be useful in many cases.
I can't get any callback value with on** method
import 'package:flutter/material.dart';
import 'package:sleek_circular_slider/sleek_circular_slider.dart';
void main() => runApp(const MyApp());
/// This is the main application widget.
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: _title,
home: MyStatefulWidget(),
);
}
}
/// This is the stateful widget that the main application instantiates.
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
@override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
String percentageModifier(double value) {
final roundedValue = value.ceil().toInt().toString();
return '$roundedValue %';
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
child: SleekCircularSlider(
appearance: CircularSliderAppearance(
spinnerDuration: 2000,
spinnerMode: false,
startAngle: 270,
angleRange: 360,
customColors:
CustomSliderColors(progressBarColor: Colors.red),
customWidths: CustomSliderWidths(progressBarWidth: 10),
infoProperties:
InfoProperties(modifier: percentageModifier)),
min: 0,
max: 100,
initialValue: 45,
onChange: (double value) {
print('onChange...');
print('value: $value');
},
onChangeStart: (double startValue) {
print('onChangeStart...');
print('startValue: $startValue');
},
onChangeEnd: (double endValue) {
print('onChangeEnd...');
print('endValue: $endValue');
},
),
),
],
),
),
),
);
}
}
I have a CircularSlider that has max values that are not static, as they are dependant on what the user sets the value to be. This caused an exception:
EXCEPTION CAUGHT BY WIDGETS LIBRARY
The following UnsupportedError was thrown building SliderLabel(dirty):
I/flutter ( 5516): Unsupported operation: Infinity or NaN toInt
This feature will open a lot more customizability to the seek bar handle as it is not constrained to a circle where we can only set the color. Also other features that are internally implemented (labels, track shape border) may maybe also be lifted as a Widget so we can customize it.
If max value equals min value, an unhandled exception is thrown by this code because it attempts to divide by zero:
final divider = (max - min) / 100;
return (value - previous).abs() ~/ divider * 15;
shadowWidth is misspelled under the CustomSliderWidths parameters section.
SleekCircularSlider seems to be a StatefulWidget so when changing the state of the progress bar colour it just keeps it's initial colour. What would be the best way to update the progress bar colour without rebuilding the page?
Is there a way to make custom handler, like icon widget or canvas?
Hi,
It would be a very great enhancement if we could customize the handler appearance too(for example drawing a triangle instead of a circle), is it possible for you to implement such a feature?
I hope you fix this.
How can I make the gradient be the full color spectrum even if the progress is only partial? For instance, if the progress is only 0.2, I actually want to see the whole sweep from blue to red. Not just the blue part
Another flutter widget has this same issue:
diegoveloper/flutter_percent_indicator#31
any clue how to solve this?
This is an amazing widget. I got 90% of the requirement using this widget, due to it's ability to customise.
It would be great if it would have ability to change the dot's radius (size) and colour and dot stroke's width and colour.
Awsome Widget pal!
Just a suggestion, easy to implement. I miss a readonly property and saw it is just a few lines change.
bool get _interactionEnabled => !widget.readOnly && (widget.onChangeEnd != null || widget.onChange != null && !widget.appearance.spinnerMode);
It would be great!
Thanks in advance
I'm trying to dynamically change it from a spinner to an initalValue. When I change the spinnerMode property from an outside widget I see this:
_SleekCircularSliderState is a SingleTickerProviderStateMixin but multiple tickers were created.
It would be great to be able to change that on the fly.
Hello
I was searching for a circle slider and i found yours , thanks for it ^^
so i'm using it for playing an audio , and i need to change it's value depends on my audio position, is there any way to handle this ?
The sliding direction is only clock-wise direction as far as I understand. It would be great to add a property implying the sliding direction, it can be either clock-wise direction or counter clockwise direction.
I don't what action leads to this :
The following _CastError was thrown while dispatching a pointer event:
Null check operator used on a null value
When the exception was thrown, this was the stack:
#0 _SleekCircularSliderState._onPanDown (package:sleek_circular_slider/src/circular_slider.dart:285:58)
#1 _CustomPanGestureRecognizer.addPointer (package:sleek_circular_slider/src/custom_gesture_recognizer.dart:16:18)
#2 RawGestureDetectorState._handlePointerDown (package:flutter/src/widgets/gesture_detector.dart:1205:18)
#3 RenderPointerListener.handleEvent (package:flutter/src/rendering/proxy_box.dart:2829:29)
#4 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:419:22)
...
Event: PointerDownEvent#4ef6d(position: Offset(233.0, 349.6))
position: Offset(233.0, 349.6)
Target: RenderPointerListener#a3f84 relayoutBoundary=up9
parentData: <none> (can use size)
constraints: BoxConstraints(unconstrained)
size: Size(150.0, 150.0)
behavior: deferToChild
listeners: down
====================================================================================================
Hi there,
Im working with the package as a progressbar.
I use 3 colors inside: progressBarColors
But it looks like the color is repeating itself? Im starting with a green color, then a yellow and then a red.
But at the beginning Im seeing a small yellow color and then the green, then yellow again.
Is there any possibility to fix this?
Could you please add a gauge visualization chart to this library? Awesome package btw.
I have used a button widget inside SleekCircularSlider()
but when button is disabled, I want to disable the slide property of the slider and vice versa .
In other words, I want to do enable/ disable slider based on a boolean value.
I was wondering if is there any way to make this thing possible as I was unable to find any parameter that would be helpful in my case.
The stroke cap of the progress bar paint is hardcoded as round. As a result, it doesn't show the exact value, but adds extra as seen in the image below. The value is 50% but the cap makes it look more. I would like to have an option to remove the cap.
final progressBarPaint = Paint()
..shader = progressBarGradient.createShader(progressBarRect)
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..strokeWidth = appearance.progressBarWidth;
This may seems strange but it actually gives an error when I set the initial value equals to the same min value.
I currently solved it by increase the initial value by 2.
Here's my code.
@override
Widget build(BuildContext context) {
return SleekCircularSlider(
initialValue: widget.value <= widget.min ? widget.value + 2 : widget.value,
innerWidget: _buildInnerWidget,
appearance: CircularSliderAppearance(
size: 200,
customWidths: CustomSliderWidths(
trackWidth: 2,
progressBarWidth: 10,
),
customColors: CustomSliderColors(
progressBarColors: [
const Color(0xffe74c3c),
const Color(0xffe67e22),
const Color(0xfff1c40f),
],
trackColor: Colors.white12,
shadowColor: const Color(0xffe74c3c),
),
animationEnabled: true,
),
min: widget.min,
max: widget.max,
onChange: (val) => setState(() => currentValue = val),
onChangeEnd: (val) => widget.onChaged(val),
);
}
The error was in the framework since multiple things went wrong too inside the framework..
The following assertion was thrown building Expanded(flex: 1):
'package:flutter/src/widgets/framework.dart': Failed assertion: line 4224 pos 12: '!_dirty': is not true.Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=BUG.md
Hope you can fix it as soon as possible.
Thanks.
Thanks for the amazing widget. I found when I set the max to 2000, the actual limit will be 2001. The print value from onChange is "I/flutter (29316): 2000.0000000000002". I am not sure if I am doing something wrong or this is a bug. Thanks
Updated: weird... the actual max limit will be affected by the min value. If I set min:6 max:2000 then the actual max will be 2001. set min other than 6 will be fine.
Now that flutter released 2.0, I think most developers will upgrade.
Would be nice to have this lib updated with null-safety so people using it can migrate.
Hi dear
thank you for helping us by introducing this amazing slider.
Actually I don't have issue but I ask you to add more features like make it work as a progress indicator.
Thank you
It will be awesome to be able to set value labels (initially for min/max, later for divisions) that are rendered on a curved path outside/inside the track path.
Functionality request: Animation Duration parameter when using the slider as a static progress bar instead of a slider.
When I say animation duration, I mean being able to set the duration it takes for the progress bar to go from zero to the value set.
Side note: This is the best slider package out there for Flutter, and an enormous kudos to the authors!!
I'm using SleekCircularSlider in a StreamBuilder to show the audio player's progress. Also, users could use the slider to seek the player.
The problem is that method onChange
is called even when the user is not selecting the slider. Here is my code:
Widget positionIndicator(MediaItem mediaItem, PlaybackState state,
AudioProcessingState processingState) {
if (processingState == AudioProcessingState.none) {
return SleekCircularSlider(
appearance: CircularSliderAppearance(
spinnerMode: true,
size: 225,
customWidths: CustomSliderWidths(trackWidth: 4, progressBarWidth: 13)));
}
double seekPos;
return StreamBuilder(
stream: Rx.combineLatest2<double, double, double>(
_dragPositionSubject.stream,
Stream.periodic(Duration(milliseconds: 200)),
(dragPosition, _) => dragPosition),
builder: (context, snapshot) {
double position =
snapshot.data ?? state.currentPosition.inMilliseconds.toDouble();
double duration = mediaItem?.duration?.inMilliseconds?.toDouble();
print("positionIndicator $position/$duration ${state.processingState}");
return Column(
children: [
if (duration != null &&
!(position == 0 && state.processingState != AudioProcessingState.ready))
SleekCircularSlider(
appearance: CircularSliderAppearance(
size: 225,
startAngle: 270,
angleRange: 360,
customWidths:
CustomSliderWidths(trackWidth: 4, progressBarWidth: 13)),
min: 0.0,
max: duration,
initialValue: seekPos ?? max(0.0, min(position, duration)),
innerWidget: (double percentage) => Text(''),
onChange: (double value) {
print('on change');
_dragPositionSubject.add(value);
},
onChangeEnd: (value) {
print('on change end');
AudioService.seekTo(Duration(milliseconds: value.toInt()));
seekPos = value;
_dragPositionSubject.add(null);
},
),
if (duration == null ||
(position == 0 && state.processingState != AudioProcessingState.ready))
SleekCircularSlider(
appearance: CircularSliderAppearance(
spinnerMode: true,
size: 225,
customWidths:
CustomSliderWidths(trackWidth: 4, progressBarWidth: 13))),
],
);
},
);
}
Hey, cool package!
I start my slider from startAngle: 270 and angleRange: 360. So it spins around like a clock.
I then want to apply a gradient of three colors progressing from red to yellow to green.
But I can't start gradient from gradientStartAngle: 270, because it doesn't work if I set the gradientEndAngle to 630 (270+360) or any other solutions I could think of.
Did I simply misunderstood? Couldn't google any solutions.
I have done a temporary fix by setting it gradientStart: 0 and end: 360 and then settings colors as yellow, green, red, but it doesn't seem like a great fix :-)
Hello! Could you please tell how to use the modifier? It asks for some kind on String Function(double). Didn't find any info about that type in Google.
We are able to control only one variable, it would be really useful (Specially for time intervals, timers, etc) to be able to control two variables within the range. For example: initValue and endValue.
Like how davidanaya's flutter-circular-slider does
Changing the UI either via animation or changing the appearance values (and calling setState) does not rebuild the widget. This causes the slider appearance to be static on creation but unable to update.
Awesome widget!
innerWidget not shown in spinnerMode by default, is there any possible to show innerWidget when spinnerMode set true, cause I want to show some tips inside where use as spinner.
Thanks in advance.
EDIT: I was experimenting with it in a wrong way, it indeed responds to external changes of state.
Can we add markers around the slider, for eg. creating a clock so can we have markings around the circle denoting 12,3,6 & 9 ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.