searchfield
searchfield copied to clipboard
FocusNode listener is not removed
Describe the bug
When using SearchField with an external FocusNode provided, there is an exception coming from the listener attached to it. I think this is because the previously attached listener is still there after a dispose as it is not removed (with removeListener).
To Reproduce Steps to reproduce the behavior:
- Provide a FocusNode to the SearchField
- Make the widget tree rebuild
- Interact with the field (click / type)
- See error
- [x] By clicking this checkbox, I confirm I am using the latest version of the package found on pub.dev/searchfield
Expected behavior
There should be no exception.
Actual behavior
════════ Exception caught by foundation library ════════════════════════════════
The following assertion was thrown while dispatching notifications for FocusNode:
This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.
When the exception was thrown, this was the stack:
#0 State.context.<anonymous closure> (package:flutter/src/widgets/framework.dart:954:9)
framework.dart:954
#1 State.context (package:flutter/src/widgets/framework.dart:960:6)
framework.dart:960
#2 _SearchFieldState.initialize.<anonymous closure> (package:searchfield/src/searchfield.dart:467:13)
searchfield.dart:467
#3 ChangeNotifier.notifyListeners (package:flutter/src/foundation/change_notifier.dart:439:24)
change_notifier.dart:439
#4 FocusNode._notify (package:flutter/src/widgets/focus_manager.dart:1130:5)
focus_manager.dart:1130
#5 FocusManager.applyFocusChangesIfNeeded (package:flutter/src/widgets/focus_manager.dart:1987:12)
focus_manager.dart:1987
(elided 10 frames from dart:async)
Additional context
The issue is not present when there is no externally provided FocusNode, since it is disposed here:
https://github.com/maheshj01/searchfield/blob/29e794d60ee38b3b3daadd7cb4d0428d4f424696/lib/src/searchfield.dart#L428-L430
Based on my tests moving the listener function to a private method and eg. adding the else branch after these lines containing _searchFocus!.removeListener(_searchFocusListener); can solve this issue.