-
Notifications
You must be signed in to change notification settings - Fork 26.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exception on ExpansionPanel toggle due to Duplicate Global Keys #13780
Comments
I had the same issue today with ExpansionPanel, it seems to happen when |
I am also getting this
Adding my own key to the ExpansionPanelList seems to solve the issue |
Today I faced the same error:
When I investigate more in my code, I found the reason for this error: I have items list in a shared class across my app. In the build method of the first page in my app, I fill the list with the required elements ( before return the In the home of the When running the application for the first time there is no issue, but when I click hot reload, my list item filled again (this is my bug, I moved the filling code to the I just shared what's happening to me, in order if you can take advantages from it. Thanks.
|
@FlutterIODev Can you please create a runnable minimal production ( |
Of course I will create a runnable example ASAP. |
@zoechi , Here a small example that describes the error when happening to me. After starting the program try to press hot reload and then expand and collapse the panels. import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: "test",
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List<Item> items = [];
Widget _buildPanel() {
return ExpansionPanelList(
children: _buildLevelsPanels(),
expansionCallback: (int panelIndex, bool isExpanded) {
bool newValue = !items[panelIndex].isExpanded;
items[panelIndex].isExpanded = newValue;
setState(() {
isExpanded = newValue;
});
},
);
}
List<ExpansionPanel> _buildLevelsPanels() {
List<ExpansionPanel> result = [];
items.forEach((Item item) {
result.add(ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) => ListTile(
title: Text(
item.id.toString(),
textAlign: TextAlign.center,
),
onTap: () {
setState(() {
item.isExpanded = !item.isExpanded;
});
},
),
body: Text("Hello"),
isExpanded: item.isExpanded));
});
return result;
}
@override
Widget build(BuildContext context) {
items.addAll(List.generate(5, (int index) => Item(index)));
return Scaffold(
appBar: AppBar(),
body: ListView(
children: [
_buildPanel(),
],
),
);
}
}
class Item {
final int id;
bool isExpanded = true;
Item(this.id);
} |
Any updates on this? I am also facing same issue. |
I'm not sure what exactly causes the issue but having this line in items.addAll(List.generate(5, (int index) => Item(index))); looks like a really bad idea Build is called frequently and adding items when build happens doesn't make sense. |
I closed #24210 as duplicate because this has more upvotes but #24210 has a good reproduction example like #24210 (comment) |
I'm seeing the exact same thing, if I leave the initial state of all my Expansion Panels to false everything is fine. If I set any of them to true I get the exception when opening the collapsed panel. |
I had the same problem using bool shouldAppendGap(Panel item) =>
item != visibleItems.last && item.isExpanded;
bool shouldPrependGap(Panel item) =>
item != visibleItems.first && item.isExpanded;
MaterialGap appendGap(Panel item) => MaterialGap(
key: ValueKey<int>(context.hashCode ^ item.hashCode ^ 'post'.hashCode),
);
MaterialGap prependGap(Panel item) => MaterialGap(
key: ValueKey<int>(context.hashCode ^ item.hashCode ^ 'pre'.hashCode),
);
Iterable<MergeableMaterialItem> buildItems(Panel item) => item.isVisible
? <MergeableMaterialItem>[
shouldPrependGap(item) && !shouldAppendGap(prev(item))
? prependGap(item)
: null,
buildItem(item),
shouldAppendGap(item) ? appendGap(item) : null
].whereType<MergeableMaterialItem>()
: const <MergeableMaterialItem>[];
@override
MergeableMaterial build(BuildContext context) => MergeableMaterial(
hasDividers: true,
children:
widget.children.expand<MergeableMaterialItem>(buildItems).toList(),
); |
It seems changing the number of children of |
As far as I can tell, it appears that issue may be arising from misusing the @Monotoba could you please share some code to reproduce your error?
My current goal would be to update the API docs to have a clear example on how to use ExpansionPanel, and also link it to the example app in flutter_gallery. |
I am getting the same thing using a Streambuilder to provide the List data for the expansion list. I want to add a new item to the ExpansionPanel children list and also have it expanded, the new widget is rendered correctly and expanded, but the next time setState() is called for any reason, I get After collapsing the new child, or calling setState() again, the error disappears. I can also avoid the error completely if I collapse the new child before calling setState(). It feels like dynamically adding expanded items to a pre-existing ExpansionPanelList children doesn't work properly, is there any clarification regarding this? I am following the samples closely apart from having a StreamBuilder that feeds the list |
@hawkinsjb1 Could you share a minimal code sample where I can reproduce the problem? |
@hawkinsjb1 I have the exact same issue. If another panel is expanded and a new item is added to the list adjacent to the expanded panel, attempting to expand the new item causes this error. It appears when the framework attempts to layout the list it expects there to be a gap above and below the currently expanded item, however adding the item to the list doesn't rebuild the ExpansionPanelList, you should be able to see that there will be no gap between your dynamically added item and the expanded panel. I worked around this by providing a ValueKey that was the length of the list, e.g. |
@krooq Could you share a code sample that reproduces the problem? |
Hi together, I'm aware that my code looks a bit strange (e.g. not using a FutureBuilde) but that's monestly because i tried to delete everything not needed to reproduce the error.. I would be thankful for every help :) Code:
Error:
flutter doctor
|
@ehhc Thank you for providing a code sample, stack trace and the output of I cleaned up the indentations a little and added some more boilerplate so that it's easily reproducible, in case anybody else wants to take a stab at it as well. |
@shihaohong thanks :) yeah, i think, it's more related to #24210, which in turns was closed as a duplicated of this issue. Therefore, i posted here.. :) |
@shihaohong did you already have time to look into it? Do you have any idea what i can do to avoid the error? I really like the collapsible panels, but if i can't avoid the problem, i might have to replace them with something else ( :( ) |
@ehhc I'm still trying to come up with a robust solution, but I've already somewhat identified the cause of the problem. It seems like #19624 introduced the issue while implementing I assume that this error occurs whenever unique layout situations occur, such as when using |
@shihaohong thanks for your quick reply and for looking into it. I think modifying sdk-code (even as a workaround) for my real application can't be a good solution, can it? Anyway: thanks a lot for your help! |
@shihaohong i fear the issue is still not solved. I tried to reproduce it with the example app i posted above (this one: #13780 (comment)). If i do the following:
after a while the following error occurs:
I think your patch made the error happen less reproducable and it happens less often, but it still happens... :(
|
@shihaohong is this the right place for the issue or should i create a new issue? |
@ehhc I've just reproduced the error. Lets reopen this issue and we can investigate this further. Thanks for bringing this up and having a detailed steps to reproduce the error! |
I found a fix that involves using Keys. When the list that backs my ExpansionPanelList changes in size, I generate a new key and provide that to the ExpansionPanelList. Looks like the following: if (_previousList.length != _currentList.length) {
key = Key("${++count}");
}
_previousList = List.of(_currentList);
var expansionList = ExpansionPanelList(
key: key,
expansionCallback: _doExpansion,
children: childPanels,
); |
Thanks @Kropie 's solution. I think by giving a new key when rebuilding the if this is not a |
I believe this has been fixed with #49896 (more info in #43780). It turns out that this was a result of a problem with the I tested it in |
I have the same issue. Trackback:
Info:
|
In my case, where I feed a stream to |
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of |
This most likely is me doing something wrong. However, I thought I had this working... I get this error when trying to add a column with content to an ExpansionPanel. The error only occurs at runtime when I try to expand more than one panel at a time. The app is a simple one inspired by the holidays. It is a simple Holiday Shopping List. It contains an image and text in the top 40% of the page. In the remaining 60% or so, it contains a ListView with a Container ->Column>Row->Columns. The app is laid out as a dynamically generated list of Giftees (people we are shopping for), each contains a sub-list of gifts (gift we may purchase. I want to embed an few IconButtons but the Panel header can't handle that. It runs out of room. So I removed them.
If you need the code for this. let me know.
Steps to Reproduce
Please tell us what you were doing and what went wrong. If you are running flutter tools from the command line, please try adding the
-v
or--verbose
option to gather more information.If the problem is with your application's rendering, please attach a screenshot and any relevant source code.
If you are getting an exception in the logs, and your code is implicated in the first few frames, then please include the source code for the functions involved.
Logs
Run your application with
flutter run
and attach all the log output.Run
flutter analyze
and attach any output of that command also.Flutter Doctor
Paste the output of running
flutter doctor
here.The text was updated successfully, but these errors were encountered: