trio_switch 1.1.0
trio_switch: ^1.1.0 copied to clipboard
A customizable tri-state switch widget for Flutter. Allows users to select one of three states with a smooth sliding indicator animation.
import 'package:flutter/material.dart';
import 'package:trio_switch/trio_switch.dart';
void main() {
runApp(const ExampleApp());
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'TrioSwitch Example',
theme: ThemeData(
colorSchemeSeed: Colors.blue,
useMaterial3: true,
),
home: const ExamplePage(),
);
}
}
class ExamplePage extends StatefulWidget {
const ExamplePage({super.key});
@override
State<ExamplePage> createState() => _ExamplePageState();
}
class _ExamplePageState extends State<ExamplePage> {
int _basicValue = 1;
int _themedValue = 0;
int _disabledValue = 2;
int _mediaValue = 1;
int _sizeValue = 0;
int _partialDisabledValue = 1;
int _lockedValue = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('TrioSwitch Examples')),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Basic usage
_buildSection(
title: 'Basic Usage',
child: TrioSwitch(
value: _basicValue,
onChanged: (v) => setState(() => _basicValue = v),
icons: const [
Icon(Icons.close),
Icon(Icons.remove),
Icon(Icons.check),
],
),
stateValue: _basicValue,
),
const SizedBox(height: 32),
// Custom themed
_buildSection(
title: 'Custom Themed',
child: TrioSwitch(
value: _themedValue,
onChanged: (v) => setState(() => _themedValue = v),
icons: const [
Icon(Icons.sentiment_dissatisfied),
Icon(Icons.sentiment_neutral),
Icon(Icons.sentiment_satisfied),
],
trackDecoration: BoxDecoration(
color: Colors.deepPurple.shade50,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.deepPurple.shade200),
),
indicatorDecoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.deepPurple, Colors.deepPurple.shade300],
),
borderRadius: BorderRadius.circular(18),
boxShadow: [
BoxShadow(
color: Colors.deepPurple.withValues(alpha: 0.3),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
activeIconColor: Colors.white,
inactiveIconColor: Colors.deepPurple.shade300,
borderRadius: 20,
height: 56,
),
stateValue: _themedValue,
),
const SizedBox(height: 32),
// Disabled state
_buildSection(
title: 'Disabled State',
child: TrioSwitch(
value: _disabledValue,
onChanged: (v) => setState(() => _disabledValue = v),
icons: const [
Icon(Icons.close),
Icon(Icons.remove),
Icon(Icons.check),
],
disabled: true,
),
stateValue: _disabledValue,
),
const SizedBox(height: 32),
// Partially disabled segments
_buildSection(
title: 'Partially Disabled (first segment disabled)',
child: TrioSwitch(
value: _partialDisabledValue,
onChanged: (v) =>
setState(() => _partialDisabledValue = v),
icons: const [
Icon(Icons.close),
Icon(Icons.remove),
Icon(Icons.check),
],
disabledStates: const [true, false, false],
),
stateValue: _partialDisabledValue,
),
const SizedBox(height: 32),
// Locked on selected (all others disabled)
_buildSection(
title: 'Locked Selection (only first enabled & selected)',
child: TrioSwitch(
value: _lockedValue,
onChanged: (v) => setState(() => _lockedValue = v),
icons: const [
Icon(Icons.lock_open),
Icon(Icons.lock),
Icon(Icons.lock),
],
disabledStates: const [false, true, true],
),
stateValue: _lockedValue,
),
const SizedBox(height: 32),
// Media controls
_buildSection(
title: 'Media Controls',
child: TrioSwitch(
value: _mediaValue,
onChanged: (v) => setState(() => _mediaValue = v),
icons: const [
Icon(Icons.skip_previous),
Icon(Icons.pause),
Icon(Icons.skip_next),
],
indicatorColor: Colors.teal,
trackColor: Colors.teal.shade50,
activeIconColor: Colors.white,
inactiveIconColor: Colors.teal.shade300,
),
stateValue: _mediaValue,
),
const SizedBox(height: 32),
// Size labels
_buildSection(
title: 'Size Selector',
child: TrioSwitch(
value: _sizeValue,
onChanged: (v) => setState(() => _sizeValue = v),
icons: const [
Text('S', style: TextStyle(fontWeight: FontWeight.bold)),
Text('M', style: TextStyle(fontWeight: FontWeight.bold)),
Text('L', style: TextStyle(fontWeight: FontWeight.bold)),
],
width: 160,
height: 44,
indicatorColor: Colors.orange,
trackColor: Colors.orange.shade50,
),
stateValue: _sizeValue,
),
],
),
),
);
}
Widget _buildSection({
required String title,
required Widget child,
required int stateValue,
}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: Theme.of(context).textTheme.titleMedium),
const SizedBox(height: 12),
child,
const SizedBox(height: 8),
Text('Current value: $stateValue',
style: Theme.of(context).textTheme.bodySmall),
],
);
}
}