Instantly share code, notes, and snippets.
Created
March 29, 2023 11:24
-
Star
(2)
2
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save sahildev001/8c3a52c5828554c4d3e9c5446da1d9ea to your computer and use it in GitHub Desktop.
This class create Gradient slider button in dart.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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