Open In App

How to Get Coordinates Widgets using rect_getter Package in Flutter?

Improve
Improve
Like Article
Like
Save
Share
Report

Sometimes we need to get a widget’s location or show some overlay widget or something similar over a widget whose location on the screen could be dynamic. In this article, we are going to discuss the way to get coordinates of a widget using the rect_getter package. Follow the steps below :

1. Create an App:

Create a new flutter app by running the below command on your terminal:

flutter create your_app_name

Now open your flutter project in any IDE like Android-Studio or VS-Code.

2. Create a basic UI:

Now remove all the boilerplate code from lib/main.dart and add code for your UI. For demonstration, I have created a basic UI with Columns, Rows, and Icons.

Dart




import 'package:flutter/material.dart';
  
void main() {
  runApp(MaterialApp(home: MyApp()));
}
  
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}
  
class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black26,
      appBar: AppBar(
        backgroundColor: Colors.green,
        title: Center(
          child: Text(
            'GeeksForGeeks',
            style: TextStyle(color: Colors.white,
                   fontWeight: FontWeight.bold),
          ),
        ),
      ),
      // Some basic UI with five Icons displayed in Rows and Columns
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.all(16),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            mainAxisSize: MainAxisSize.max,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Flexible(
                      flex: 1,
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      )),
                  Flexible(
                      flex: 1,
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ))
                ],
              ),
              Flexible(
                  flex: 1,
                  child: Icon(
                    Icons.message_outlined,
                    color: Colors.white,
                    size: 120,
                  )),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Flexible(
                      flex: 1,
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      )),
                  Flexible(
                      flex: 1,
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ))
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}


Output: 

3.  Now add the rect_getter Package:

To add the rect_getter package, run the below command in your terminal :

flutter pub add rect_getter

4. Importing rect_getter:

To use rect_getter import it by adding the below line in your lib/main.dart :

Dart




import 'package:rect_getter/rect_getter.dart';


5. Getting the location of a widget using rect_getter:

For every widget’s location, we want to get using rect_getter, we have to declare a specific global key for each widget. Since in this example we are trying to get the location of five widgets we need to declare five global keys. So add these lines just at the start of _MyAppState class (in this case yours might differ) :

Dart




// Defining global keys for all the widgets we
// want to get coordinates of
var globalKey1 = RectGetter.createGlobalKey(),
globalKey2 = RectGetter.createGlobalKey(),
globalKey3 = RectGetter.createGlobalKey(),
globalKey4 = RectGetter.createGlobalKey(),
globalKey5 = RectGetter.createGlobalKey();


Now wrap all five Icons (or the target widget in your case) with a GestureDetector widget and now also wrap this GestureDetector widget with a RectGetter widget. In the RectGetter widget add a key attribute and pass in a global key.

Now you can get access to the widget’s coordinates using the below code inside the onTap attribute of GesturDetector  and display the coordinates on a SnackBar:

Dart




// Add RectGetter as parent to the target widget
RectGetter(
  key: globalKey,
  child: GestureDetector(
          onTap: () {
                     // create a Rect instance
                     Rect rect = RectGetter.getRectFromKey(globalKey);
              
                     // Getting values of all four coordinate left, top, right and
                     // bottom using Rect instance 
                     var left = rect.left;
                     var top = rect.top;
                     var right = rect.right;
                     var bottom = rect.bottom;
                       
                     // Displaying the resultant coordinates in a SnackBar
                     ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                         content:
                           Text('LTRB :($left,$top,$right,$bottom)')));
                     },
                      child: YourWidget()
                    ),
                  )


After adding all this code to our lib/main.dart, our main.dart will look like this :

Dart




import 'package:flutter/material.dart';
import 'package:rect_getter/rect_getter.dart';
  
void main() {
  runApp(MaterialApp(home: MyApp()));
}
  
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}
  
class _MyAppState extends State<MyApp> {
    
  // Defining global keys for all the widgets we
  // want to get coordinates of
  var globalKey1 = RectGetter.createGlobalKey(),
      globalKey2 = RectGetter.createGlobalKey(),
      globalKey3 = RectGetter.createGlobalKey(),
      globalKey4 = RectGetter.createGlobalKey(),
      globalKey5 = RectGetter.createGlobalKey();
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black26,
      appBar: AppBar(
        backgroundColor: Colors.green,
        title: Center(
          child: Text(
            'GeeksForGeeks',
            style: TextStyle(color: Colors.white,
                             fontWeight: FontWeight.bold),
          ),
        ),
      ),
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.all(16),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            mainAxisSize: MainAxisSize.max,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Flexible(
                      
                      // Add RectGetter as parent to the target widget
                      child: RectGetter(
                    key: globalKey1,
                    child: GestureDetector(
                      onTap: () {
                          
                        // create a Rect instance
                        Rect rect = RectGetter.getRectFromKey(globalKey1);
                          
                        // Getting values of all four coordinate left, top, right and
                        // bottom using Rect instance 
                        var left = rect.left;
                        var top = rect.top;
                        var right = rect.right;
                        var bottom = rect.bottom;
                          
                        // Displaying the resultant coordinates in a SnackBar
                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                            backgroundColor: Colors.green,
                            content: Text(
                              'LTRB :($left, $top, $right, $bottom)',
                              style: TextStyle(fontWeight: FontWeight.bold),
                            )));
                      },
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ),
                    ),
                  )),
                  Flexible(
                      
                      // Add RectGetter as parent to the target widget
                      child: RectGetter(
                    key: globalKey2,
                    child: GestureDetector(
                      onTap: () {
                          
                        // create a Rect instance
                        Rect rect = RectGetter.getRectFromKey(globalKey2);
                          
                        // Getting values of all four coordinate left, top, right and
                        // bottom using Rect instance 
                        var left = rect.left;
                        var top = rect.top;
                        var right = rect.right;
                        var bottom = rect.bottom;
                          
                        // Displaying the resultant coordinates in a SnackBar
                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                            backgroundColor: Colors.green,
                            content: Text(
                              'LTRB :($left, $top, $right, $bottom)',
                              style: TextStyle(fontWeight: FontWeight.bold),
                            )));
                      },
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ),
                    ),
                  ))
                ],
              ),
              Flexible(
                  
                  // Add RectGetter as parent to the target widget
                  child: RectGetter(
                key: globalKey3,
                child: GestureDetector(
                  onTap: () {
                    //create a Rect instance
                    Rect rect = RectGetter.getRectFromKey(globalKey3);
                      
                    // Getting values of all four coordinate left, top, right and
                    // bottom using Rect instance 
                    var left = rect.left;
                    var top = rect.top;
                    var right = rect.right;
                    var bottom = rect.bottom;
                      
                    // Displaying the resultant coordinates in a SnackBar
                    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                        backgroundColor: Colors.green,
                        content: Text(
                          'LTRB :($left, $top, $right, $bottom)',
                          style: TextStyle(fontWeight: FontWeight.bold),
                        )));
                  },
                  child: Icon(
                    Icons.message_outlined,
                    color: Colors.white,
                    size: 120,
                  ),
                ),
              )),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Flexible(
                      
                      // Add RectGetter as parent to the target widget
                      child: RectGetter(
                    key: globalKey4,
                    child: GestureDetector(
                      onTap: () {
                        //create a Rect instance
                        Rect rect = RectGetter.getRectFromKey(globalKey4);
                          
                        // Getting values of all four coordinate left, top, right and
                        // bottom using Rect instance 
                        var left = rect.left;
                        var top = rect.top;
                        var right = rect.right;
                        var bottom = rect.bottom;
  
                        // Displaying the resultant coordinates in a SnackBar
                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                            backgroundColor: Colors.green,
                            content: Text(
                              'LTRB :($left, $top, $right, $bottom)',
                              style: TextStyle(fontWeight: FontWeight.bold),
                            )));
                      },
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ),
                    ),
                  )),
                  Flexible(
                      
                      // Add RectGetter as parent to the target widget
                      child: RectGetter(
                    key: globalKey5,
                    child: GestureDetector(
                      onTap: () {
                          
                        // create a Rect instance
                        Rect rect = RectGetter.getRectFromKey(globalKey5);
                          
                        // Getting values of all four coordinate left, top, right and
                        // bottom using Rect instance 
                        var left = rect.left;
                        var top = rect.top;
                        var right = rect.right;
                        var bottom = rect.bottom;
                          
                        // Displaying the resultant coordinates in a SnackBar
                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                            backgroundColor: Colors.green,
                            content: Text(
                              'LTRB :($left, $top, $right, $bottom)',
                              style: TextStyle(fontWeight: FontWeight.bold),
                            )));
                      },
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ),
                    ),
                  ))
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}


Output: 

App Demo1

5. Showing widgets overlay by using the coordinates

I have used the coordinates from rect_getter to show a notification dot over our widget using Overlay. Check the code below :

Dart




import 'package:flutter/material.dart';
import 'package:rect_getter/rect_getter.dart';
  
void main() {
  runApp(MaterialApp(home: MyApp()));
}
  
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}
  
class _MyAppState extends State<MyApp> {
  var globalKey1 = RectGetter.createGlobalKey(),
      globalKey2 = RectGetter.createGlobalKey(),
      globalKey3 = RectGetter.createGlobalKey(),
      globalKey4 = RectGetter.createGlobalKey(),
      globalKey5 = RectGetter.createGlobalKey();
  
  showOverlayDot(BuildContext context,
                 double left, double top) async {
    OverlayState overlayState = Overlay.of(context);
    OverlayEntry overlayEntry;
    overlayEntry = OverlayEntry(builder: (context) {
      return Positioned(
          left: left,
          top: top,
          child: Icon(
            Icons.circle,
            color: Colors.red,
          ));
    });
  
    overlayState.insert(overlayEntry);
    await Future.delayed(Duration(seconds: 2));
    overlayEntry.remove();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black26,
      appBar: AppBar(
        backgroundColor: Colors.green,
        title: Center(
          child: Text(
            'GeeksForGeeks',
            style: TextStyle(color: Colors.white,
                             fontWeight: FontWeight.bold),
          ),
        ),
      ),
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.all(16),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            mainAxisSize: MainAxisSize.max,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Flexible(
                      child: RectGetter(
                    key: globalKey1,
                    child: GestureDetector(
                      onTap: () {
                        Rect rect = RectGetter.getRectFromKey(globalKey1);
                        var left = rect.left;
                        var top = rect.top;
                        var right = rect.right;
                        var bottom = rect.bottom;
  
                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                            backgroundColor: Colors.green,
                            content: Text(
                              'LTRB :($left, $top, $right, $bottom)',
                              style: TextStyle(fontWeight: FontWeight.bold),
                            )));
                        showOverlayDot(this.context, left, top);
                      },
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ),
                    ),
                  )),
                  Flexible(
                      child: RectGetter(
                    key: globalKey2,
                    child: GestureDetector(
                      onTap: () {
                        Rect rect = RectGetter.getRectFromKey(globalKey2);
                        var left = rect.left;
                        var top = rect.top;
                        var right = rect.right;
                        var bottom = rect.bottom;
  
                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                            backgroundColor: Colors.green,
                            content: Text(
                              'LTRB :($left, $top, $right, $bottom)',
                              style: TextStyle(fontWeight: FontWeight.bold),
                            )));
                        showOverlayDot(this.context, left, top);
                      },
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ),
                    ),
                  ))
                ],
              ),
              Flexible(
                  child: RectGetter(
                key: globalKey3,
                child: GestureDetector(
                  onTap: () {
                    Rect rect = RectGetter.getRectFromKey(globalKey3);
                    var left = rect.left;
                    var top = rect.top;
                    var right = rect.right;
                    var bottom = rect.bottom;
  
                    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                        backgroundColor: Colors.green,
                        content: Text(
                          'LTRB :($left, $top, $right, $bottom)',
                          style: TextStyle(fontWeight: FontWeight.bold),
                        )));
                    showOverlayDot(this.context, left, top);
                  },
                  child: Icon(
                    Icons.message_outlined,
                    color: Colors.white,
                    size: 120,
                  ),
                ),
              )),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Flexible(
                      child: RectGetter(
                    key: globalKey4,
                    child: GestureDetector(
                      onTap: () {
                        Rect rect = RectGetter.getRectFromKey(globalKey4);
                        var left = rect.left;
                        var top = rect.top;
                        var right = rect.right;
                        var bottom = rect.bottom;
  
                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                            backgroundColor: Colors.green,
                            content: Text(
                              'LTRB :($left, $top, $right, $bottom)',
                              style: TextStyle(fontWeight: FontWeight.bold),
                            )));
                        showOverlayDot(this.context, left, top);
                      },
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ),
                    ),
                  )),
                  Flexible(
                      child: RectGetter(
                    key: globalKey5,
                    child: GestureDetector(
                      onTap: () {
                        Rect rect = RectGetter.getRectFromKey(globalKey5);
                        var left = rect.left;
                        var top = rect.top;
                        var right = rect.right;
                        var bottom = rect.bottom;
  
                        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                            backgroundColor: Colors.green,
                            content: Text(
                              'LTRB :($left, $top, $right, $bottom)',
                              style: TextStyle(fontWeight: FontWeight.bold),
                            )));
                        showOverlayDot(this.context, left, top);
                      },
                      child: Icon(
                        Icons.message_outlined,
                        color: Colors.white,
                        size: 70,
                      ),
                    ),
                  ))
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}


Output: 

App Demo 2



Last Updated : 06 Oct, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads