| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- class GradientSwitch extends StatefulWidget {
- final bool value;
- final Future<bool> Function(bool)? onChanged;
- final double width;
- final double height;
- final Duration animationDuration;
- final double indicatorSize;
- final LinearGradient selectedGradient;
- final LinearGradient unselectedGradient;
- final Color? loadingColor;
- const GradientSwitch({
- super.key,
- required this.value,
- this.onChanged,
- this.width = 60.0,
- this.height = 30.0,
- this.animationDuration = const Duration(milliseconds: 300),
- this.indicatorSize = 24.0,
- this.selectedGradient =
- const LinearGradient(colors: [Colors.blue, Colors.purpleAccent]),
- this.unselectedGradient =
- const LinearGradient(colors: [Color(0xFFEEEEEE), Color(0xFFBDBDBD)]),
- this.loadingColor,
- });
- @override
- State<GradientSwitch> createState() => _GradientSwitchState();
- }
- class _GradientSwitchState extends State<GradientSwitch>
- with SingleTickerProviderStateMixin {
- late bool _currentValue;
- bool _isLoading = false;
- @override
- void initState() {
- super.initState();
- _currentValue = widget.value;
- }
- @override
- void didUpdateWidget(GradientSwitch oldWidget) {
- super.didUpdateWidget(oldWidget);
- if (widget.value != _currentValue && !_isLoading) {
- _currentValue = widget.value;
- }
- }
- Future<void> _handleTap() async {
- if (_isLoading || widget.onChanged == null) return;
- setState(() => _isLoading = true);
- final targetValue = !_currentValue;
- bool? success;
- try {
- success = await widget.onChanged!(targetValue);
- } finally {
- setState(() => _isLoading = false);
- if (success != null && mounted) {
- setState(() => _currentValue = success!);
- }
- }
- }
- @override
- void dispose() {
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return GestureDetector(
- onTap: _handleTap,
- child: AnimatedContainer(
- duration: widget.animationDuration,
- width: widget.width,
- height: widget.height,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(widget.height / 2),
- gradient: _currentValue
- ? widget.selectedGradient
- : widget.unselectedGradient,
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.1),
- blurRadius: 4,
- offset: const Offset(0, 2),
- )
- ],
- ),
- child: AnimatedAlign(
- duration: widget.animationDuration,
- alignment:
- _currentValue ? Alignment.centerRight : Alignment.centerLeft,
- child: Container(
- margin: const EdgeInsets.symmetric(horizontal: 3),
- width: widget.indicatorSize,
- height: widget.indicatorSize,
- decoration: BoxDecoration(
- shape: BoxShape.circle,
- color: Colors.white,
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.2),
- blurRadius: 4,
- offset: const Offset(0, 2),
- )
- ],
- ),
- child: _isLoading
- ? Center(
- child: CupertinoActivityIndicator(
- color: widget.loadingColor,
- radius: widget.indicatorSize * 0.3,
- ),
- )
- : null, // 非加载状态不显示内容
- ),
- ),
- ),
- );
- }
- }
|