Skip to content

Instantly share code, notes, and snippets.

@sahildev001
Created March 29, 2023 11:24
Show Gist options
  • Save sahildev001/8c3a52c5828554c4d3e9c5446da1d9ea to your computer and use it in GitHub Desktop.
Save sahildev001/8c3a52c5828554c4d3e9c5446da1d9ea to your computer and use it in GitHub Desktop.
This class create Gradient slider button in dart.
import 'package:flutter/material.dart';
class GradientSliderButton extends StatefulWidget {
/// the width of the SlidableButton
final double width;
/// the height of the SlidableButton
final double height;
/// the size of the draggable icon
final double iconSize;
/// the borderRAdius of the SlidableButton
final double borderRadius;
/// the text shown in the SlidableButton
final String text;
// the text shown in slider complete
final String submitText;
/// the style of the text shown in the SlidableButton
final TextStyle? textStyle;
/// the icon of the sliderButtonIcon [ wich the user drag]
final IconData? sliderButtonIcon;
/// the duration of the animation when the user slide the button
final Duration animationDuration;
/// this function will called when the user slide the button
final VoidCallback onSubmit;
/// the gradient of the submitted par of the container
final Gradient? gradient;
/// the background color of the button
final Color backgroundColor;
/// the background color of the button when submit call
final Color? submitBackgroundColor;
// the icon color
final Color? iconColor;
// Submit icon background color
final Color? submitIconColor;
/// the icon when the user submit
final IconData? submittedIcon;
/// the draggable icon of the SlidableButton
final IconData dragableIcon;
/// the background of the draggable icon of the SlidableButton
final Color? dragableIconBackgroundColor;
/// you can also add your costom draggable widget
final Widget? draggableWidget;
GradientSliderButton(
{Key? key,
required this.onSubmit,
this.width = 300,
this.height = 52,
this.iconSize = 22,
this.borderRadius = 52,
this.text = "Slide after arrival",
this.textStyle,
this.iconColor,
this.submitIconColor,
this.submitText = "Arrived!",
this.submitBackgroundColor,
this.dragableIconBackgroundColor,
this.submittedIcon,
this.draggableWidget,
this.dragableIcon = Icons.arrow_forward_ios,
this.sliderButtonIcon,
this.animationDuration = const Duration(milliseconds: 300),
this.gradient,
required this.backgroundColor})
: assert(width != double.infinity, "width should not be equal infinity"),
assert(iconSize <= height,
"the size of the icon {iconSize} should be < height"),
super(key: key);
@override
State<GradientSliderButton> createState() =>
_GradientSliderButtonState();
}
class _GradientSliderButtonState extends State<GradientSliderButton>
with SingleTickerProviderStateMixin {
/// default Values
double _position = 0;
bool _submitted = false;
@override
Widget build(BuildContext context) {
double position_percent = _position / (widget.width - 2 * widget.height);
print("position Percent :-- ${position_percent}");
return AnimatedContainer(
duration: widget.animationDuration,
height: widget.height,
width: widget.width,
decoration: BoxDecoration(
color:!_submitted? widget.backgroundColor:widget.submitBackgroundColor,
borderRadius: BorderRadius.circular(widget.borderRadius),
// gradient: !_submitted ? null : widget.gradient
),
alignment: Alignment.center,
child: ClipRRect(
borderRadius: BorderRadius.circular(52),
child: Stack(
children: [
Align(
alignment: Alignment.centerRight,
child: _submitted
? Container(
height: widget.height,
width: widget.height-16,
margin: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(52),
color: widget.dragableIconBackgroundColor,
),
child: Icon(widget.submittedIcon ?? Icons.done,color: widget.submitIconColor ,))
: Stack(
children: [
Positioned(
top: 0,
right: 0,
left: 0,
bottom: 0,
child: Row(
children: [
AnimatedContainer(
duration: const Duration(milliseconds: 70),
height: widget.height,
width: _position + widget.height,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(52),
color: widget.submitBackgroundColor,
// gradient: widget.gradient
),
),
],
)),
Positioned(
top: 0,
right: 0,
left: 0,
bottom: 0,
child: Opacity(
opacity:
1 - (position_percent > 1 ? 1 : position_percent),
child: Center(
child: Text(widget.text,
style: widget.textStyle ??
const TextStyle(
color: Colors.white, fontSize: 15)),
),
)),
Positioned(
top: 0,
right: 0,
left: 0,
bottom: 0,
child: Row(
children: [
GestureDetector(
onPanUpdate: (details) async {
_position += details.delta.dx;
if (_position < 0) {
_position = 0;
setState(() {});
} else if (_position >=
(widget.width - widget.height - 20)) {
_position = widget.width - widget.height;
if (!_submitted) {
_submitted = true;
setState(() {});
Duration _dur = const Duration(milliseconds: 200) +
(widget.animationDuration);
await Future.delayed(_dur);
if (mounted) widget.onSubmit();
return;
}
_submitted = true;
setState(() {});
}
setState(() {});
},
onPanEnd: (_) {
position_percent = 0;
_position = 0;
setState(() {});
},
child: AnimatedPadding(
duration: const Duration(milliseconds: 70),
padding: EdgeInsets.only(left: _position),
child: widget.draggableWidget ??
_draggableWidget(
iconSize: widget.height,
backgroundColor: _position == 0?widget.backgroundColor:null,
gradient: widget.gradient,
iconColor: widget.iconColor,
dragableIconBackground: widget.dragableIconBackgroundColor,
dragableIcon: widget.dragableIcon,
),
),
),
],
),
),
Positioned(
top: 0,
right: 0,
left: 0,
bottom: 0,
child: Opacity(
opacity: (position_percent > 1 ? 1 : 0)
,
child: Center(
child: Text(widget.submitText,
style: widget.textStyle ??
const TextStyle(
color: Colors.white, fontSize: 15)),
),
)),
],
),
),
Positioned(
top: 0,
right: 0,
left: 0,
bottom: 0,
child: Opacity(
opacity: (position_percent > 1 ? 1 : 0)
,
child: Center(
child: Text(widget.submitText,
style: widget.textStyle ??
const TextStyle(
color: Colors.white, fontSize: 15)),
),
))
],
),
),
);
}
}
class _draggableWidget extends StatelessWidget {
final double iconSize;
final Gradient? gradient;
final Color? dragableIconBackground;
final IconData dragableIcon;
final Color? iconColor;
final Color? backgroundColor;
const _draggableWidget(
{Key? key,
required this.iconSize,
this.gradient,
this.dragableIconBackground,
this.iconColor,
this.backgroundColor,
required this.dragableIcon})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
color: backgroundColor,
child: Container(
height: iconSize,
width: iconSize-16,
margin: EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(52),
color: dragableIconBackground,
gradient: dragableIconBackground != null ? null : gradient),
alignment: Alignment.center,
child: Icon(dragableIcon,color: iconColor,),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment