Flutter define coordinates of the pressed point of a button

Viewed 186

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

3 Answers

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.

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. 
  ),
)

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),
  );
}
Related