0

Problem:

enter image description here

When I encountered this problem, I was looking to get the middle position of words contained inside a pressed widget.

I am getting the error, Multiple widgets used the same GlobalKey, while using the minimum viable code below.

I am at a loss for solving this problem. I am injecting GlobalKeys, which should be unique, and I would expect them to be different from one another. The code does work, but it's a bit frustrating that I cannot find the solution.

What I have tried:

I have tried, to no avail, several solutions from previously posted issues on StackOverflow, including using different variations of Globalkeys with unique identifiers and making a class with static Globalkeys variables:

How to Fix a 'Multiple Widgets used the same Globalkey resource 1

How to Fix a 'Multiple Widgets used the same Globalkey resource 2

How to Fix a 'Multiple Widgets used the same Globalkey resource 3

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  final scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      body: SafeArea(
        child: Row(
          mainAxisSize: MainAxisSize.max,
          children: [LeftSideWidget()],
        ),
      ),
    );
  }
}

class DisplayCircle extends StatelessWidget {
  final Color color;

  DisplayCircle({Key? key, required this.color}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 120,
      height: 120,
      clipBehavior: Clip.antiAlias,
      decoration: BoxDecoration(
        shape: BoxShape.circle,
      ),
      child: CircleAvatar(
        backgroundColor: color,
      ),
    );
  }
}

class LeftSideWidget extends StatefulWidget {
  const LeftSideWidget({
    Key? key,
  }) : super(key: key);

  @override
  _LeftSideWidgetState createState() => _LeftSideWidgetState();
}

class _LeftSideWidgetState extends State<LeftSideWidget> {
  double thumbWidth = 70.0;
  var position = 0.0;

  changePosition(GlobalKey key) {
    final RenderObject? object = key.currentContext!.findRenderObject();
    final RenderBox renderBox = object as RenderBox;
    final size = object.semanticBounds;
    position = renderBox.localToGlobal(Offset.zero).dy;
    setState(() {
      position = (size.center.dy + position - (thumbWidth / 2));
      print(position.toString());
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisSize: MainAxisSize.max,
      children: [
        Spacer(),
        WordsToPress(
          title: 'TEST LINE 1',
          key: GlobalKey(),
          onPressed: (GlobalKey key) => changePosition(key),
        ),
        Spacer(),
        WordsToPress(
          title: 'TEST LINE 2',
          key: GlobalKey(),
          onPressed: (GlobalKey key) => changePosition(key),
        ),
        Spacer(),
        WordsToPress(
          title: 'TEST LINE 3',
          key: GlobalKey(),
          onPressed: (GlobalKey key) => changePosition(key),
        ),
        Spacer(),
      ],
    );
  }
}

class WordsToPress extends StatelessWidget {
  final String title;
  final GlobalKey key;

  final Function(GlobalKey) onPressed;

  const WordsToPress(
      {required this.title, required this.key, required this.onPressed})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapUp: (_) => onPressed(key),
      child: Container(
        key: key,
        child: RotatedBox(
          quarterTurns: -1,
          child: Text(
            title,
          ),
        ),
      ),
    );
  }
}

Question: How do I properly use Globalkeys to ensure that there is only one per widget? Any help would be greatly appreciated.

George Lee
  • 814
  • 18
  • 34

1 Answers1

3

You are using the same key for the Widget called WordsToPress and for the Container inside of it in every instance.

t00n
  • 395
  • 5
  • 12
  • I’m not sure what you mean? I am injecting a new Globalkey() to the constructor of WordsToPress, which is used to instantiate the widget. The widget also has a Callback method that passes the globalkey to it. I’m not sure how this is causing the same globalkey to be used in two or more different widgets. I would love some insight to this. – George Lee Aug 09 '21 at 13:30
  • That's correct, WordsToPress is getting injected the new Globalkey but that GlobalKey injected, is used too for the Container (that's a widget too) in the build method of the WordsToPress widget. First use of the Globalkey: const WordsToPress( {required this.title, required this.key, required this.onPressed}) : super(key: key); Second use of the Globalkey: Container( key: key, child: RotatedBox( quarterTurns: -1, child: Text( title, ), ), – t00n Aug 10 '21 at 06:12
  • Thank you very much. For some reason, I had thought that it would only be used in the container widget. In hindsight, this is completely clear to me now. I appreciate it. – George Lee Aug 10 '21 at 10:49