I am trying to add a Positioned widget to a relative location after doing a hit test. The path goes as follows Listener -> ListView -> SizedBox -> Container.

I have tried to access variables within the returned path, but documentation is limited on how to do this.

    Listener listener = new Listener(
        onPointerUp: (PointerUpEvent event) {
                      print('${event.position}');
            final RenderBox box = context.findRenderObject();
                          final Offset localOffset =
                  box.globalToLocal(event.position);
                 var res = BoxHitTestResult();
                 box.hitTest(res, position:localOffset);
                 for(var r in res.path)
                 {
                   print(r);
                 }

        },
        child: Container()
);
RenderConstrainedBox#fffda relayoutBoundary=up27 dart_sdk.js:19110:15
RenderRepaintBoundary#3afc3 relayoutBoundary=up26 dart_sdk.js:19110:15
RenderIndexedSemantics#57986 relayoutBoundary=up25 dart_sdk.js:19110:15
RenderSliverList#46e30 relayoutBoundary=up24 dart_sdk.js:19110:15
RenderPointerListener#b70ac relayoutBoundary=up19 dart_sdk.js:19110:15
RenderSemanticsGestureHandler#8224c relayoutBoundary=up18 dart_sdk.js:19110:15
RenderPointerListener#62c4e relayoutBoundary=up17 dart_sdk.js:19110:15
_RenderScrollSemantics#fc217 relayoutBoundary=up16 dart_sdk.js:19110:15
RenderRepaintBoundary#be170 relayoutBoundary=up15 dart_sdk.js:19110:15
RenderCustomPaint#385db relayoutBoundary=up14 dart_sdk.js:19110:15
RenderRepaintBoundary#3d0ab relayoutBoundary=up13 dart_sdk.js:19110:15
RenderRepaintBoundary#a3e3b relayoutBoundary=up12 dart_sdk.js:19110:15
RenderCustomPaint#83c0b relayoutBoundary=up11 dart_sdk.js:19110:15
RenderRepaintBoundary#c3ec5 relayoutBoundary=up10 dart_sdk.js:19110:15
RenderPadding#0cbae relayoutBoundary=up9 dart_sdk.js:19110:15
RenderDecoratedBox#760d1 relayoutBoundary=up8 dart_sdk.js:19110:15
RenderFlex#41bef relayoutBoundary=up7 dart_sdk.js:19110:15
RenderCustomMultiChildLayoutBox#939e4 relayoutBoundary=up6 dart_sdk.js:19110:15
_RenderInkFeatures#a1c5e relayoutBoundary=up5 dart_sdk.js:19110:15
RenderPhysicalModel#19c78 relayoutBoundary=up4 dart_sdk.js:19110:15
RenderPointerListener#e553e relayoutBoundary=up3 dart_sdk.js:19110:15
RenderSemanticsGestureHandler#dbe00 relayoutBoundary=up2 dart_sdk.js:19110:15
RenderPointerListener#0ce7e relayoutBoundary=up1

I expect to either be able to access and change the widget directly, or call an event inside of the widget in question, convert the supplied position to a position relative to that container, then add a positioned widget using relative coordinates.


Solution 1: TheArchitect

The solution is to attach a global key to a widget then wrap it in meta data providing the key as the data. Meta data seems to be the main way to communicate from the widget layer to the rendering engine and back.

MetaData( 
          metaData: widget.key,  
          child: Container(
          height: 50,
          width: 50,
              ),
            ));

then, the meta data object can be accessed from the hit test to get the global key attached.

    Listener listener = new Listener(
        onPointerUp: (PointerUpEvent event) {
          print('${event.position}');
          final RenderBox box = context.findRenderObject();
          final Offset localOffset = box.globalToLocal(event.position);
          print(box);
          var res = BoxHitTestResult();
          box.hitTest(res, position: localOffset);
          for (var r in res.path) {
            if (r.target is RenderMetaData) {
              var target = r.target as RenderMetaData;
              print(target.metaData);
            }
          }
        });

Now that we've found the global key from the rendering pipeline, we can easily search a map or list containing our keys to find the actual widget object and update as needed.