Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple widgets used the same GlobalKey

Tags:

I'm using Flutter. I have a simple app with 3 tabs. There is a RefreshIndicator in each tab with a ListView. The rows are built in another method. This is the code:

 @override  Widget build(BuildContext context) {     final GlobalKey<RefreshIndicatorState> _RIKey1 = new GlobalKey<RefreshIndicatorState>();     final GlobalKey<RefreshIndicatorState> _RIKey2 = new GlobalKey<RefreshIndicatorState>();     final GlobalKey<RefreshIndicatorState> _RIKey3 = new GlobalKey<RefreshIndicatorState>();      debugPrint(_RIKey1.toString());     debugPrint(_RIKey2.toString());     debugPrint(_RIKey3.toString());     return new Scaffold(       body: new DefaultTabController(         length: 3,         child: new Scaffold(           appBar: new AppBar(             bottom: new TabBar(               tabs: [                 new Tab(icon: new Icon(Icons.view_list)),                 new Tab(icon: new Icon(Icons.hotel)),                 new Tab(icon: new Icon(Icons.assessment)),               ],             ),             title: new Text('Data'),           ),           body: new TabBarView(             children: [               new RefreshIndicator(                 key: _RIKey1,                 onRefresh: _actualizoData,                 child: new ListView.builder(                     padding: new EdgeInsets.only(top: 5.0),                     itemCount: linea_reservas.length * 2,                     itemBuilder: (BuildContext context, int position) {                       if (position.isOdd) return new Divider();                       final index = position ~/ 2;                       return _buildRow(index);                     }),               ),               new RefreshIndicator(                 key: _RIKey2,                 onRefresh: _actualizoData,                 child: new ListView.builder(                     padding: new EdgeInsets.only(top: 8.0),                     itemCount: linea_inouthouse.length * 2,                     itemBuilder: (BuildContext context, int position) {                       if (position.isOdd) return new Divider();                       final index = position ~/ 2;                       return _buildRowInOutHouse(index);                     }),               ),               new RefreshIndicator(                 key: _RIKey3,                 onRefresh: _actualizoData,                 child: new ListView.builder(                     padding: new EdgeInsets.only(top: 5.0),                     itemCount: linea_ocupacion.length * 2,                     itemBuilder: (BuildContext context, int position) {                       if (position.isOdd) return new Divider();                       final index = position ~/ 2;                       return _buildRowOcupacion(index);                     }),               ),             ],           ),         ),       ),     );   } 

I'd added the debugPrints and the output are 6 lines, instead of 3.

I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#4d76c] I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#59b9e] I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#2c88b] I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#7bd42] I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#1c984] I/flutter ( 5252): [LabeledGlobalKey<RefreshIndicatorState>#dbe20] 

the app works, but after changing tabs a few times, it crashes with this error:

    I/flutter ( 5252): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter ( 5252): The following assertion was thrown building NotificationListener<KeepAliveNotification>: I/flutter ( 5252): Multiple widgets used the same GlobalKey. I/flutter ( 5252): The key [LabeledGlobalKey<RefreshIndicatorState>#7bd42] was used by multiple widgets. The parents of I/flutter ( 5252): those widgets were: I/flutter ( 5252): - RepaintBoundary-[<[LabeledGlobalKey<RefreshIndicatorState>#7bd42]>](renderObject: I/flutter ( 5252):   RenderRepaintBoundary#60a4a DETACHED) I/flutter ( 5252): - RepaintBoundary-[<[LabeledGlobalKey<RefreshIndicatorState>#7bd42]>](renderObject: I/flutter ( 5252):   RenderRepaintBoundary#c8cdb NEEDS-LAYOUT NEEDS-PAINT) I/flutter ( 5252): A GlobalKey can only be specified on one widget at a time in the widget tree. 

The keys are generated in the Build method, so, I don't understand why the Multiple widgets used the same GlobalKey error

Why the key is generated again, and why it's not unique? I'm not talking of a thousand intents, the error appears after changing between tabs 4 or 5 times. Thank you for any help.

like image 825
Alex Angelico Avatar asked Apr 16 '18 16:04

Alex Angelico


People also ask

How can multiple widgets uses the same global key in flutter?

They are using the same key because when you create the FormBuilderWrapper you pass the key to it, and then inside you return a formBuilder passing the same key you gave the FormBuilderWrapper .


2 Answers

Could you create your keys "by hand" and use static/constant values? e.g. ...

import 'package:flutter/widgets.dart';  class RIKeys {   static final riKey1 = const Key('__RIKEY1__');   static final riKey2 = const Key('__RIKEY2__');   static final riKey3 = const Key('__RIKEY3__'); } 

then in ...

    body: new TabBarView(             children: [               new RefreshIndicator(new RefreshIndicator( // Use the Manual Static Value instead ...                 key: RIKeys.riKey1,                 onRefresh: _actualizoData,                 child: new ListView.builder(                     padding: new EdgeInsets.only(top: 5.0),                     itemCount: linea_reservas.length * 2,                     itemBuilder: (BuildContext context, int position) {                       if (position.isOdd) return new Divider();                       final index = position ~/ 2;                       return _buildRow(index);                     }),               ), 

I have done this in a similar situation with some success ... especially with redux or other similar patterns ...

like image 137
babernethy Avatar answered Sep 29 '22 02:09

babernethy


this code worked for me ... I want to create a List of Form Key ...

just Changing GlobalKey with GlobalObjectKey

like below.

final List<GlobalObjectKey<FormState>> formKeyList = List.generate(10, (index) => GlobalObjectKey<FormState>(index)); 
like image 45
mohandesR Avatar answered Sep 29 '22 01:09

mohandesR