'Flutter: How to Fix a 'Multiple Widgets Used the Same GlobalKey' Error
Problem:
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.
Solution 1:[1]
You are using the same key for the Widget called WordsToPress and for the Container inside of it in every instance.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | t00n |