Skip to content

Instantly share code, notes, and snippets.

@epatel
Created June 16, 2024 19:54
Show Gist options
  • Save epatel/1954a42b7ee8edbb15d315b67e166fd3 to your computer and use it in GitHub Desktop.
Save epatel/1954a42b7ee8edbb15d315b67e166fd3 to your computer and use it in GitHub Desktop.
Path + Positioned Widgets
import 'dart:math' show Random;
import 'package:flutter/material.dart';
List<bool> checkmarks = List.generate(10, (_) => false);
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
),
);
}
class HomePage extends StatefulWidget {
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
double checkBoxSize = computeCheckBoxSize(context);
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) {
final height = constraints.biggest.height;
final width = constraints.biggest.width;
return Stack(
children: [
Container(color: Colors.amber.shade100),
Positioned.fill(child: CustomPaint(painter: TestPathPainter())),
...points.indexed
.map(
(point) => Positioned(
left: point.$2.dx * width - checkBoxSize / 2,
top: point.$2.dy * height - checkBoxSize / 2,
child: Checkbox(
value: checkmarks[point.$1],
onChanged: (_) {
setState(() {
checkmarks[point.$1] = !checkmarks[point.$1];
});
},
),
),
)
.toList(),
],
);
},
),
);
}
}
double computeCheckBoxSize(BuildContext context) {
final ThemeData themeData = Theme.of(context);
final MaterialTapTargetSize effectiveMaterialTapTargetSize =
themeData.checkboxTheme.materialTapTargetSize ??
themeData.materialTapTargetSize;
final VisualDensity effectiveVisualDensity =
themeData.checkboxTheme.visualDensity ?? themeData.visualDensity;
Size size;
switch (effectiveMaterialTapTargetSize) {
case MaterialTapTargetSize.padded:
size = const Size(kMinInteractiveDimension, kMinInteractiveDimension);
break;
case MaterialTapTargetSize.shrinkWrap:
size = const Size(
kMinInteractiveDimension - 8.0, kMinInteractiveDimension - 8.0);
break;
}
size += effectiveVisualDensity.baseSizeAdjustment;
return size.longestSide;
}
class TestPathPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 2.0
..color = Colors.black;
final path = Path()
..moveTo(
points[0].dx * size.width,
points[0].dy * size.height,
);
points.sublist(1).forEach(
(point) => path.lineTo(
point.dx * size.width,
point.dy * size.height,
),
);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(TestPathPainter oldDelegate) => false;
}
final random = Random();
final List<Offset> points = List.generate(
10,
(index) => Offset(.1 + random.nextDouble() * .8, .1 + index * .8 / 9),
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment