George Lee
George Lee

Reputation: 882

Flutter: How to Fix a 'Multiple Widgets Used the Same GlobalKey' Error

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.

Upvotes: 2

Views: 10110

Answers (1)

t00n
t00n

Reputation: 415

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

Upvotes: 5

Related Questions