Flutter define coordinates of the pressed point of a button

120

Solution 1

As you're also using TextButton, GestureDetector.onTap wouldn't help you to get the details, so we'll use onPanDown. All you need to do is wrap your TextButton in a GestureDetector like this:

Container(
  height: 30,
  child: GestureDetector(
    onPanDown: (details) {
      // You're looking for these values. 
      final globalPosition = details.globalPosition;
      final globalDx = globalPosition.dx;
      final globalDy = globalPosition.dy;
      
      final localPosition = details.localPosition;
      final localDx = localPosition.dx;
      final localDy = localPosition.dy;
    },
    child: TextButton(...), // Your TextButton code goes here. 
  ),
)

Solution 2

You can use a GestureDetector:

GestureDetector(
        onTapDown: (TapDownDetails details) => print(details.localPosition),
        onTapUp: (TapUpDetails details) => print(details.localPosition),
        child: Container(
    ...

But you will need to remove the TextButton because it will interfere with the the onTapDown and onTapUp closures.

Solution 3

Screenshot:

enter image description here

I think you should use another approach to handle your case. This is a basic sample to give you an idea, feel free to play around with the layout and its values.


Code:

int _price = 90;
  
@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Center(
      child: ClipRRect(
        borderRadius: BorderRadius.circular(12),
        child: Material(
          color: Colors.green[400],
          child: SizedBox(
            width: 100,
            height: 40,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                _buildIcon(
                  onPressed: () => setState(() => _price--),
                  icon: Icon(Icons.remove),
                ),
                Text('€ $_price'),
                _buildIcon(
                  onPressed: () => setState(() => _price++),
                  icon: Icon(Icons.add),
                ),
              ],
            ),
          ),
        ),
      ),
    ),
  );
}
  
Widget _buildIcon({required VoidCallback onPressed, required Icon icon}) {
  return InkWell(
    onTap: onPressed,
    child: Center(child: icon),
  );
}
Share:
120
Vasya2014
Author by

Vasya2014

Updated on November 23, 2022

Comments

  • Vasya2014
    Vasya2014 over 1 year

    I make a button with two side action, first reduce item count and second side increase item count, I need get coordinates of the pressed point of the button.

    I used GestureDetector with onTapDown but it have a delay.

    Thanks.

    GestureDetector(
              onTapDown: _handleTapDown
    )
    
    void _handleTapDown(TapDownDetails details) {
        final RenderBox referenceBox = context.findRenderObject() as RenderBox;
        setState(() {
          final touchPoint = referenceBox.globalToLocal(details.globalPosition);
          if (touchPoint.dx <= width of btn) {
            print(touchPoint.dx);
          } else {
            print("-----${touchPoint.dx}");
          }
        });
      }
    

    current code

        Container(
            height: 30,
            child: TextButton(
              style: ButtonStyle(
                  backgroundColor: MaterialStateProperty.all(Design.appColor),
                  padding: MaterialStateProperty.all(EdgeInsets.symmetric(vertical: 8, horizontal: 10)),
                  shape: MaterialStateProperty.all(RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(10.0),
                  ))
              ),
              onPressed: (){
              },
              child: Container(
                child: RichText(
                  text:  TextSpan(
                    text: "",
                    children:[
                      WidgetSpan(
                        alignment: PlaceholderAlignment.middle,
                        child: Icon(Icons.remove, size: 14, color: Colors.white),
                      ),
                      TextSpan(
                        text: "  ${widget.model[index].sale?.minPrice ?? widget.model[index].sale?.price} ₽  ",
                        style: TextStyle(
                            color: Colors.white,
                            fontSize: 14,
                            fontWeight: FontWeight.w500,
                            fontFamily: "Inter"
                        ),
                      ),
                      WidgetSpan(
                        alignment: PlaceholderAlignment.middle,
                        child: Icon(Icons.add, size: 14, color: Colors.white),
                      )
                    ],
                  ),
                ),
              ),
            ),
          );
    

    enter image description here