Im a flutter beginner and making a drawing app that can draw lines only with stylus device.
my test app can draw lines with finger and stylu but I want to implement the function that can draw lines only with a stylus.
I know there's a PointerData class and PointerDeviceKind.stylus enum. but I dont know how to use this class.
Here's my code and I used the provider.
OHHH I found the GestureRecognizer constructor and it says It's possible to limit this recognizer to a specific set of PointerDeviceKinds by providing the optional supportedDevices argument. haha but I have no idea how to apply this constructor to my code...
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ChangeNotifierProvider(
create: (context) => DrawingProvider(), child: BlankPage()),
);
}
}
class BlankPage extends StatefulWidget {
const BlankPage({Key? key}) : super(key: key);
@override
State<BlankPage> createState() => _BlankPageState();
}
class _BlankPageState extends State<BlankPage> {
@override
Widget build(BuildContext context) {
var p = Provider.of<DrawingProvider>(context);
return GestureDetector(
child: Scaffold(
body: Column(
children: [
Row(
children: [
penWidget(p: p),
colorWidget(context: context, color: Colors.black),
],
),
Expanded(
child: Stack(
children: [
Center(
child: Image(
image: AssetImage('image/image1.jpg'),
fit: BoxFit.cover,
),
),
Positioned.fill(
child: CustomPaint(
painter: DrawingPainter(p.lines),
),
),
GestureDetector(
behavior: HitTestBehavior.translucent,
onPanDown: (s) {
p.penMode ? p.penDrawStart(s.localPosition) : null;
},
onPanUpdate: (s) {
p.penMode ? p.penDrawing(s.localPosition) : null;
},
child: Container(
child: Listener(
behavior: HitTestBehavior.opaque,
onPointerDown: (_) {
print("컨테이너 눌림");
},
),
),
),
],
),
),
],
)),
);
}
}
class DrawingPainter extends CustomPainter {
DrawingPainter(this.lines);
final List<List<DotInfo>> lines;
@override
void paint(Canvas canvas, Size size) {
for (var oneLine in lines) {
Color? color;
double? size;
var path = Path();
var l = <Offset>[];
for (var oneDot in oneLine) {
color ??= oneDot.color;
size ??= oneDot.size;
l.add(oneDot.offset);
}
path.addPolygon(l, false);
canvas.drawPath(
path,
Paint()
..color = color!
..strokeWidth = size!
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke
..isAntiAlias = true);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
drawing_provider.dart
class DrawingProvider extends ChangeNotifier {
final lines = <List<DotInfo>>[];
double _penSize = 3;
double get penSize => _penSize;
Color _selectedColor = Colors.black;
Color get selectedColor => _selectedColor;
bool _penMode = false;
bool get penMode => _penMode;
void changePenMode() {
_penMode = !_penMode;
print("penMode is called : ${penMode} ");
_eraseMode = false;
_highlighterMode = false;
notifyListeners();
}
void penDrawStart(Offset offset) {
var oneLine = <DotInfo>[];
oneLine.add(DotInfo(offset, penSize, _selectedColor));
lines.add(oneLine);
notifyListeners();
}
void penDrawing(Offset offset) {
lines.last.add(DotInfo(offset, penSize, _selectedColor));
print("Drawing");
notifyListeners();
}
I solved this problem by using
Listenerwidget,onPointerDownandonPointerMove,onPointerCancel