I´m trying to control a Expansiontile via a tilecontroler, but as soon as I integrate it, the app is broken when I klick the tile.
Sorry, I´m new to Flutter. Any hints?
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
class MyWidget extends StatefulWidget {
const MyWidget({super.key});
@override
State<MyWidget> createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
int selectedTile = -1;
final tileControllers = List.generate(5, (_) => ExpansionTileController());
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
key: UniqueKey(),
itemCount: 5,
itemBuilder: (context, index) {
return ExpansionTile(
key: Key(index.toString()),
controller: tileControllers[index],
initiallyExpanded: index == selectedTile,
title: Text('ExpansionTile $index'),
subtitle: const Text('Trailing expansion arrow icon'),
onExpansionChanged: ((newState) {
if (newState) {
setState(() {
selectedTile = index;
});
} else {
setState(() {
selectedTile = -1;
});
}
}),
children: [
ListTile(
title: Text('This is tile number $index'),
),
],
);
},
),
);
}
}
Here is the error message:
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building _SelectionKeepAlive(state:
_SelectionKeepAliveState#94f0c):
‘package:flutter/src/material/expansion_tile.dart’: Failed assertion: line 607 pos 12:
‘widget.controller?._state == null’: is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially
more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.yml
The relevant error-causing widget was:
ListView-[#5648c]
ListView:file:///Users/michaelroebbeling/development/Flutter-Files/SportApp-Flutter/lib/screens/EditTraining.dart:19:22
The above error is thrown because when onExpansionChanged is called, the state is already updating, so you cannot call setState(() {}) in onExpansionChanged. Also, since ExpansionTile controls its own state, you can do the following and it will expand/collapse the ExpansionTile widget.
class _MyWidgetState extends State<MyWidget> {
int selectedTile = -1;
final tileControllers = List.generate(5, (_) => ExpansionTileController());
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
key: UniqueKey(),
itemCount: 5,
itemBuilder: (context, index) {
return ExpansionTile(
key: Key(index.toString()),
controller: tileControllers[index],
//initiallyExpanded: index == selectedTile,
title: Text('ExpansionTile $index'),
subtitle: const Text('Trailing expansion arrow icon'),
onExpansionChanged: (bool newState) {
if (newState) {
selectedTile = index;
} else {
selectedTile = -1;
}
},
children: [
ListTile(
title: Text('This is tile number $index'),
),
],
);
},
),
);
}
}
1