Put fixed points on PhotoView in Flutter

912 views Asked by At

Before I tell you my problem, I want to tell you what is my app doing. I have a PhotoView widget library which allows me to zoom in/out my image. And I have a GestureDetector widget which detects when it is a long press it gets LocalPosition (dy, dx) and displays a MaterialButton(point) on my PhotoView widget. Everything is working fine until now

But my problem is at the moment I zoom in on the PhotoView, MaterialButtons(points) added on the image are not in the same position. I will let a photo to see when is a normal image and zoomed in.

I don't really know what should I do, I just want the MaterialButton to stay in the same spot for normal view and zoom view too.

Code where I add a position for MaterialButton and display each point

  return Container(
                      child: Stack(
                        children: <Widget>[
                          GestureDetector(
                            onLongPressStart: (LongPressStartDetails details) {
                              var positionX = details.localPosition.dx - 40;
                              var positionY = details.localPosition.dy;
                              Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                      builder: (context) => AddTaskScreen(
                                          positionX: positionX.toString(),
                                          positionY: positionY.toString(),
                                          project: widget.project,
                                          pdfDocument: widget.pdfDocument,
                                          user: widget.user)));
                            },
                            child: PhotoView(
                              imageProvider: NetworkImage(data),
                            ),
                          ),
                          for (int i = 0; i < state.taskList.length; i++)
                            Positioned(
                              top: double.parse(state.taskList[i].positionY),
                              left: double.parse(state.taskList[i].positionX),
                              child: MaterialButton(
                                onPressed: () {
                                  Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                          builder: (context) =>
                                              TaskDetailScreen(
                                                task: state.taskList[i],
                                                user: widget.user,
                                                projectId: widget.project.id,
                                              )));
                                },
                                color: state.taskList[i].status == in_progress
                                    ? Colors.redAccent
                                    : Colors.green,
                                shape: CircleBorder(),
                              ),
                            )
                        ],
                      ),
                      alignment: Alignment.center,
                    );

Normal image view

Zoomed in image view

1

There are 1 answers

0
Kanan On
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: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  List<Area> areas = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: InteractiveViewer(
        boundaryMargin: EdgeInsets.zero,
        minScale: 1,
        maxScale: 4,

        child: Container(
          alignment: Alignment.center,
          child: Stack(
            children: <Widget>[
              GestureDetector(
                onLongPressStart: (LongPressStartDetails details) {
                  setState(() {
                    var positionX = details.localPosition.dx - 40;
                    var positionY = details.localPosition.dy - 15;
                    areas.add(Area(positionX, positionY));
                  });
                },
                child: Image.asset(
                  "assets/images/factory.jpg",
                  // height: 20,
                ),
              ),
              for (int i = 0; i < areas.length; i++)
                Positioned(
                  top: areas[i].positionY,
                  left: areas[i].positionX,
                  child: MaterialButton(
                    onPressed: () {

                    },
                    color: Colors.green,
                    shape: const CircleBorder(),
                  ),
                )
            ],
          ),
        ),
      ),
    );
  }
}

class Area {
  Area(this.positionX, this.positionY);

  double positionX;
  double positionY;
}