Reputation: 882
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.
Upvotes: 2
Views: 10110
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