Skip to content

Commit 3ffc247

Browse files
committed
toggle switch with label text is in progress
1 parent 6a5a249 commit 3ffc247

2 files changed

Lines changed: 332 additions & 1 deletion

File tree

example/lib/main.dart

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class MyHomePage extends StatefulWidget {
7070

7171
class _MyHomePageState extends State<MyHomePage> {
7272

73+
bool switchValue = true;
7374
@override
7475

7576
Widget build(BuildContext context) {
@@ -251,10 +252,12 @@ class _MyHomePageState extends State<MyHomePage> {
251252
Switch(
252253
onChanged: (v){},
253254
value: true,
254-
activeColor: Colors.red,
255+
// activeColor: Colors.red,
256+
activeColor: Colors.white,
255257
activeTrackColor: Colors.green,
256258
inactiveTrackColor: Colors.grey,
257259
inactiveThumbColor: Colors.black,
260+
// activeThumbImage: NetworkImage("https://cdn.pixabay.com/photo/2016/11/10/17/00/forest-1814723_960_720.jpg",),
258261

259262
),
260263

@@ -264,6 +267,7 @@ class _MyHomePageState extends State<MyHomePage> {
264267

265268
),
266269

270+
267271
GFToggle(
268272
type: GFToggleType.iosSwitch,
269273
activeColor: Colors.red,
@@ -272,7 +276,51 @@ class _MyHomePageState extends State<MyHomePage> {
272276
onChanged: (val){
273277
},
274278
value: true,
279+
minWidth: false,
280+
),
281+
282+
283+
LabeledToggle(
284+
transitionType: TextTransitionTypes.FADE,
285+
rounded: true,
286+
borderSize: 2.0,
287+
duration: Duration(milliseconds: 500),
288+
forceWidth: true,
289+
value: switchValue,
290+
onChanged: (v) {
291+
setState(() {
292+
switchValue = v;
293+
});
294+
},
295+
offBkColor: Colors.indigo,
296+
onBkColor: Colors.lightGreen,
297+
offText: "FALSE",
298+
onText: "TRUE",
299+
offThumbColor: Colors.lightGreen,
300+
onThumbColor: Colors.indigo,
301+
thumbSize: 30.0,
275302
),
303+
LabeledToggle(
304+
305+
//
306+
forceWidth: true,
307+
value: switchValue,
308+
onChanged: (v) {
309+
setState(() {
310+
switchValue = v;
311+
});
312+
},
313+
// offBkColor: Colors.white,
314+
// onBkColor: Colors.white,
315+
// onBorderColor: Colors.green,
316+
// offBorderColor: Colors.red,
317+
offText: "No",
318+
onText: "YES",
319+
offThumbColor: Colors.blue,
320+
onThumbColor: Colors.green,
321+
thumbSize: 30.0,
322+
),
323+
276324

277325
GFIconBadges(
278326

lib/components/toggle/gf_toggle.dart

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class GFToggle extends StatelessWidget {
2020
this.type,
2121
this.height,
2222
this.width,
23+
this.onText,
24+
this.offText,
25+
this.minWidth
2326
}) :super(key: key);
2427

2528

@@ -64,6 +67,17 @@ class GFToggle extends StatelessWidget {
6467
final double width;
6568

6669

70+
///text for the labeled Switch when it is true
71+
final String onText;
72+
73+
///text for the labled switch when it is false
74+
final String offText;
75+
76+
77+
///minwidth of the switch for labeled switch
78+
final bool minWidth;
79+
80+
6781
@override
6882
Widget build(BuildContext context) {
6983
if (type == GFToggleType.androidSwitch) {
@@ -82,10 +96,279 @@ class GFToggle extends StatelessWidget {
8296
return CupertinoSwitch(
8397
value: value,
8498
onChanged: onChanged,
99+
activeColor: activeColor,
100+
101+
102+
);
103+
104+
} else if (type == GFToggleType.labeledSwitch){
105+
return Switch(value: value, onChanged: onChanged,
106+
85107

86108

87109
);
88110

111+
89112
}
90113
}
114+
}
115+
116+
enum TextTransitionTypes { ROTATE, SCALE, FADE, SIZE }
117+
118+
class LabeledToggle extends StatefulWidget {
119+
final Widget child;
120+
final String onText;
121+
final String offText;
122+
final Color onTextColor;
123+
final Color offTextColor;
124+
final Color onThumbColor;
125+
final Color offThumbColor;
126+
final Color onBorderColor;
127+
final Color offBorderColor;
128+
final Color onBkColor;
129+
final Color offBkColor;
130+
final bool value;
131+
final double thumbSize;
132+
final double borderSize;
133+
final Duration duration;
134+
final Curve curve;
135+
final ValueChanged<bool> onChanged;
136+
final bool forceWidth;
137+
final bool rounded;
138+
final TextTransitionTypes transitionType;
139+
final bool rotationAnimation;
140+
141+
const LabeledToggle(
142+
{Key key,
143+
this.value = false,
144+
this.onText = "",
145+
this.offText = "",
146+
this.onThumbColor,
147+
this.offThumbColor,
148+
this.onBorderColor,
149+
this.offBorderColor,
150+
this.onBkColor,
151+
this.offBkColor,
152+
this.onChanged,
153+
@required this.thumbSize,
154+
this.duration = const Duration(milliseconds: 400),
155+
this.curve = Curves.linear,
156+
this.forceWidth = false,
157+
this.onTextColor = Colors.black,
158+
this.offTextColor = Colors.black,
159+
this.rounded = true,
160+
this.borderSize = 1.0,
161+
this.transitionType = TextTransitionTypes.SCALE,
162+
this.rotationAnimation = false,
163+
this.child})
164+
: assert(thumbSize != null),
165+
super(key: key);
166+
167+
const LabeledToggle.theme(
168+
{Key key,
169+
this.value = false,
170+
this.onText = "",
171+
this.offText = "",
172+
@required onColor,
173+
@required offColor,
174+
this.onChanged,
175+
@required this.thumbSize,
176+
this.duration = const Duration(milliseconds: 400),
177+
this.curve = Curves.linear,
178+
this.forceWidth = false,
179+
this.rounded = true,
180+
this.borderSize = 1.0,
181+
this.transitionType = TextTransitionTypes.SCALE,
182+
this.rotationAnimation = false,
183+
this.child})
184+
: assert(thumbSize != null),
185+
onThumbColor = offColor,
186+
onBorderColor = offColor,
187+
onBkColor = onColor,
188+
offThumbColor = onColor,
189+
offBorderColor = onColor,
190+
offBkColor = offColor,
191+
onTextColor = offColor,
192+
offTextColor = onColor,
193+
super(key: key);
194+
195+
@override
196+
_LabeledToggleState createState() => _LabeledToggleState();
197+
}
198+
199+
class _LabeledToggleState extends State<LabeledToggle>
200+
with SingleTickerProviderStateMixin {
201+
bool _value;
202+
AnimationController animationController;
203+
Animation<double> animation;
204+
205+
@override
206+
void initState() {
207+
super.initState();
208+
_value = widget.value;
209+
animationController =
210+
AnimationController(vsync: this, duration: widget.duration);
211+
CurvedAnimation curvedAnimation =
212+
CurvedAnimation(parent: animationController, curve: widget.curve);
213+
animation = Tween<double>(begin: 0.0, end: 180.0).animate(curvedAnimation)
214+
..addListener(() {
215+
setState(() {});
216+
});
217+
}
218+
219+
@override
220+
void dispose() {
221+
animationController.dispose();
222+
223+
super.dispose();
224+
}
225+
226+
@override
227+
void didUpdateWidget(LabeledToggle oldWidget) {
228+
super.didUpdateWidget(oldWidget);
229+
_value = widget.value;
230+
}
231+
232+
@override
233+
Widget build(BuildContext context) {
234+
return GestureDetector(
235+
onTap: () {
236+
widget.onChanged == null ? print("") : widget.onChanged(!_value);
237+
if (widget.rotationAnimation) {
238+
if (animationController.status == AnimationStatus.completed) {
239+
animationController.reverse();
240+
} else {
241+
animationController.forward();
242+
}
243+
}
244+
},
245+
child: Opacity(
246+
opacity: widget.onChanged == null ? 0.3 : 1.0,
247+
child: AnimatedContainer(
248+
duration: widget.duration,
249+
height: widget.thumbSize,
250+
width: widget.forceWidth ? widget.thumbSize * 2 : null,
251+
child: Stack(
252+
children: <Widget>[
253+
buildThumb(),
254+
buildLabel(),
255+
],
256+
),
257+
decoration: BoxDecoration(
258+
border: Border.all(
259+
color: widget.onChanged == null
260+
? Color(0xFFD3D3D3)
261+
: _value
262+
? (widget.onBorderColor ?? widget.onThumbColor)
263+
: (widget.offBorderColor ?? widget.offThumbColor),
264+
width: widget.borderSize),
265+
color: _value ? widget.onBkColor : widget.offBkColor,
266+
borderRadius:
267+
BorderRadius.circular(widget.rounded ? 100.0 : 0.0)),
268+
),
269+
),
270+
);
271+
}
272+
273+
Widget buildLabel() {
274+
return Padding(
275+
padding: EdgeInsets.only(
276+
right: _value ? widget.thumbSize : 1.0,
277+
left: _value ? 1.0 : widget.thumbSize),
278+
child: Row(
279+
children: <Widget>[
280+
Expanded(
281+
child: Padding(
282+
padding: const EdgeInsets.all(5.0),
283+
child: Container(
284+
height: widget.thumbSize,
285+
child: FittedBox(
286+
child: Center(
287+
child: AnimatedSwitcher(
288+
duration: widget.duration,
289+
switchInCurve: widget.curve,
290+
switchOutCurve: widget.curve,
291+
transitionBuilder:
292+
(Widget child, Animation<double> animation) {
293+
switch (widget.transitionType) {
294+
case TextTransitionTypes.ROTATE:
295+
{
296+
return RotationTransition(
297+
child: child,
298+
turns: animation,
299+
);
300+
}
301+
break;
302+
case TextTransitionTypes.FADE:
303+
{
304+
return FadeTransition(
305+
child: child,
306+
opacity: animation,
307+
);
308+
}
309+
break;
310+
311+
case TextTransitionTypes.SIZE:
312+
{
313+
return SizeTransition(
314+
child: child,
315+
sizeFactor: animation,
316+
axisAlignment: widget.value ? -5.0 : 5.0,
317+
axis: Axis.horizontal,
318+
);
319+
}
320+
break;
321+
322+
case TextTransitionTypes.SCALE:
323+
{
324+
return ScaleTransition(
325+
child: child,
326+
scale: animation,
327+
);
328+
}
329+
break;
330+
}
331+
},
332+
child: Text(
333+
_value ? widget.onText : widget.offText,
334+
key: ValueKey<bool>(_value),
335+
style: TextStyle(
336+
color: _value
337+
? widget.onTextColor
338+
: widget.offTextColor),
339+
),
340+
),
341+
),
342+
),
343+
),
344+
),
345+
),
346+
],
347+
),
348+
);
349+
}
350+
351+
Widget buildThumb() {
352+
return AnimatedAlign(
353+
curve: widget.curve,
354+
alignment: _value ? Alignment.centerRight : Alignment.centerLeft,
355+
duration: widget.duration,
356+
child: RotationTransition(
357+
turns: AlwaysStoppedAnimation(animation.value / 360),
358+
child: Padding(
359+
padding: const EdgeInsets.all(5.0),
360+
child: AnimatedContainer(
361+
duration: widget.duration,
362+
width: widget.thumbSize,
363+
height: widget.thumbSize,
364+
child: widget?.child,
365+
decoration: BoxDecoration(
366+
shape: widget.rounded ? BoxShape.circle : BoxShape.rectangle,
367+
color: _value ? widget.onThumbColor : widget.offThumbColor,
368+
),
369+
),
370+
),
371+
),
372+
);
373+
}
91374
}

0 commit comments

Comments
 (0)