Skip to content

Instantly share code, notes, and snippets.

@lopo12123
Last active June 10, 2024 14:33
Show Gist options
  • Save lopo12123/d2f2358aca0596a82294251c1827a9c8 to your computer and use it in GitHub Desktop.
Save lopo12123/d2f2358aca0596a82294251c1827a9c8 to your computer and use it in GitHub Desktop.
BadFL Example Code (BadCheckBox)
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BadCheckBox demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Example(),
);
}
}
class Example extends StatefulWidget {
const Example({super.key});
@override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
bool _v1 = false;
bool _v2 = false;
int _count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
padding: const EdgeInsets.all(16),
children: [
// Example 1: Regular Checkbox
BadCheckBox.icon(
size: 24,
icon: const Icon(Icons.check, size: 18),
checked: _v1,
border: Border.all(),
onTap: () {
setState(() {
_v1 = !_v1;
});
},
),
// Example 2: Custom Icon Builder
BadCheckBox.iconBuilder(
size: 24,
iconBuilder: (c) {
return c
? const Icon(
Icons.check,
color: Colors.green,
)
: const Icon(
Icons.close,
color: Colors.red,
);
},
checked: _v2,
onTap: () {
setState(() {
_v2 = !_v2;
});
},
),
// Example 3: Multiple States (3 states)
BadCheckBox.iconBuilder(
size: 24,
iconBuilder: (c) {
return c
? const Icon(
Icons.check,
color: Colors.green,
)
: _count % 3 == 1
? const Icon(
Icons.close,
color: Colors.red,
)
: const Icon(
Icons.remove,
color: Colors.blue,
);
},
checked: _count % 3 == 0,
onTap: () {
setState(() {
_count += 1;
});
},
),
],
),
);
}
}
// Since Dartpad does not support importing packages,
// I need to copy the necessary code here.
// You can directly use `import "package:bad_fl/bad_fl.dart"` to import it when using it
class BadClickable extends StatelessWidget {
final Widget child;
final VoidCallback onClick;
const BadClickable({
super.key,
required this.child,
required this.onClick,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onClick,
behavior: HitTestBehavior.opaque,
child: child,
);
}
}
class BadCheckBox extends StatelessWidget {
final double size;
final Widget? icon;
final Widget? Function(bool checked)? iconBuilder;
final double iconSize;
final Border? border;
final bool rounded;
final Color? fill;
final Color? fillChecked;
final bool checked;
final VoidCallback onTap;
final bool _useBuilder;
const BadCheckBox.icon({
super.key,
required this.size,
required this.icon,
double? iconSize,
this.border,
this.rounded = true,
this.fill,
Color? fillChecked,
required this.checked,
required this.onTap,
}) : iconSize = iconSize ?? size,
iconBuilder = null,
fillChecked = fillChecked ?? fill,
_useBuilder = false,
assert(icon != null, 'icon must be provided');
const BadCheckBox.iconBuilder({
super.key,
required this.size,
required this.iconBuilder,
double? iconSize,
this.border,
this.rounded = true,
this.fill,
Color? fillChecked,
required this.checked,
required this.onTap,
}) : iconSize = iconSize ?? size,
icon = null,
fillChecked = fillChecked ?? fill,
_useBuilder = true,
assert(iconBuilder != null, 'iconBuilder must be provided');
@override
Widget build(BuildContext context) {
return SizedBox(
width: size,
height: size,
child: Center(
child: BadClickable(
onClick: onTap,
child: Container(
width: size,
height: size,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
color: checked ? fillChecked : fill,
border: border,
borderRadius: rounded ? BorderRadius.circular(size / 2) : null,
),
alignment: Alignment.center,
child: SizedBox(
width: iconSize,
height: iconSize,
child: _useBuilder
? iconBuilder!(checked)
: checked
? icon
: null,
),
),
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment