Hi StackOverFlow community, that's my first question here and I'm glad to be part of this community as it already helped me in plenty of things. I looked on this topic and didn't manage to find anything. I would like to redirect the DefaultTabController to the new tab created after waiting that it's loaded and built. I managed to find a workaround with the awaiting a Future.delayed wrapping setState but I don't think it's the best solution out there. When not using this FutureDelayed I get an error due to the fact that the button function is trying to redirect to a tab not yet crated as the DefaultTabController has not been yet rebuilt.
Function for adding a new tab inside a bottomSheet
Future<int> _addNewTab() async {
await showModalBottomSheet(
...
...
IconButton(
onPressed: () {
final isValid =
_formKey.currentState!.validate();
if (!isValid) {
return;
}
Navigator.pop(context);
setState(() {
_tabs
.add(_newTab.text);
});
}
return _tabs.lenght-1;
Widget inside which I call the function
return DefaultTabController(
...
...
floatingActionButton: Padding(
//button to add a new tab
padding: const EdgeInsets.only(bottom: 25.0),
child: IconButton(
icon: Icon(
Icons.add_circle,
size: 55,
),
onPressed: () async {
var page = await _addNewTab();
//awaiting this future delayed because we can't show a page which is not built yet
await Future.delayed(const Duration(milliseconds: 10),
() {
setState(() {});
});
//moving to the new tab built after awaiting it
if (mounted) { //checking that context is still alive and usable
DefaultTabController.of(context)!.animateTo(page);
}
},
Thanks a lot for your help in advance :)
yes, you have right, using the Future to wait for the 10 milliseconds fixes it but it's not the best solution.
instead :
first import the scheduler
package, it's built-in in flutter, add this on top of your file :
import 'flutter/scheduler.dart';
then, replace this:
await Future.delayed(const Duration(milliseconds: 10),
() {
setState(() {});
});
with this:
SchedulerBinding.instance.addPostFrameCallback(
(_){
setState(() {});
})
this will schedule the SetState(() {})
just one frame after it finishes executing all the code in that onPressed
function, so the result will be an immediate SetState(() {})
after your page is on.