khush pajwani
khush pajwani

Reputation: 303

Click event on Image in custom painter

I am trying to put an click on my drawImage but how implement it I don't know I am providing the code below.

class MyApp extends StatelessWidget {
  MyApp({super.key});

  final ValueNotifier<ui.Offset> onTappedLocation =
      ValueNotifier(ui.Offset.zero);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      debugShowCheckedModeBanner: false,
      home: Container(
        color: Colors.indigo,
        child: GestureDetector(
          onTapDown: (details) {
            onTappedLocation.value = details.globalPosition;
          },
          child: Center(
              child: FutureBuilder<ui.Image>(
                  future: getImage(),
                  builder:
                      (BuildContext context, AsyncSnapshot<ui.Image> snapshot) {
                    Widget centerChild;
                    if (snapshot.hasData) {
                      centerChild = CustomPaint(
                        painter: FootballPitchPainter(
                            snapshot.data!, onTappedLocation, () {
                          print("object");
                        }),
                        size: Size(360, 480),
                      );
                    } else {
                      centerChild = const CircularProgressIndicator();
                    }
                    return centerChild;
                  })),
        ),
      ),
    );
  }
}

class FootballPitchPainter extends CustomPainter {
  final ui.Image? image;
  ValueNotifier<ui.Offset> onTappedLocation;
  VoidCallback onTap;

  FootballPitchPainter(this.image, this.onTappedLocation, this.onTap)
      : super(repaint: onTappedLocation);

  @override
  void paint(Canvas canvas, Size size) {
    final w = size.width;
    final h = size.height;

    // Other Code

    canvas.drawImage(image!, ui.Offset(100, 100), playerPaint);
    if (onTappedLocation.value == ui.Offset(100, 100)) {
      onTap();
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

Future<ui.Image> getImage() async {
  ByteData bd = await rootBundle.load('assets/logo.png');
  final Uint8List bytes = Uint8List.view(bd.buffer);
  final ui.Codec codec =
      await ui.instantiateImageCodec(bytes, targetHeight: 20, targetWidth: 20);
  final ui.Image image = (await codec.getNextFrame()).image;
  return image;
}

I have tried to implement it via gesture detector but the positions which I get on localPosition and globalPoistion are different from the custom painter offset position so I cannot implement it.

Upvotes: 0

Views: 38

Answers (1)

derdilla
derdilla

Reputation: 61

You can detect taps on any widget by wrapping them in a GestureDetector or an InkWell.

So inside your MyApps build method you can have something like:

...
Center(
  child: GestureDetector(
    onTap: () {
      // Your action
    },
    child: FutureBuilder<...

You might also want to use a more specialized widget like NetworkImage or AssetImage to load the image.

Upvotes: 0

Related Questions