I need to pass a function from one stateful widget to another.
Parent widget::
the function that I am passing is the following
void _setJobAddress(jobAddress) {
setState(() {
_jobAddress = jobAddress;
});
}
here is the button that opens the new view, this is how I am passing the function
TextButton(
onPressed: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
SearchLocationScreen(_setJobAddress)))
}
this is a little bit of the child view where I need to call the function::
class SearchLocationScreen extends StatefulWidget {
const SearchLocationScreen({Key? key}) : super(key: key);
@override
State<SearchLocationScreen> createState() => _SearchLocationScreenState();
}
class _SearchLocationScreenState extends State<SearchLocationScreen> {
Function setJobAddess; // i tried adding this, but its not working
_SearchLocationScreenState(this.setJobAddess); // i tried adding this, but its not working
List<AutocompletePrediction> placePredictions = [];
How can I make this work so that when I click a button on the child widget, the parent function passed is called?
I tried the following:
class SearchLocationScreen extends StatefulWidget {
const SearchLocationScreen(
this.setJobAddess, {
Key? key,
}) : super(key: key);
final setJobAddess;
@override
State<SearchLocationScreen> createState() => _SearchLocationScreenState();
}
class _SearchLocationScreenState extends State<SearchLocationScreen> {
//Function setJobAddess;
//_SearchLocationScreenState(this.setJobAddess);
List<AutocompletePrediction> placePredictions = [];
@override
void initState() {
widget.setJobAddess();
}
... a bunch of code that is not of importance goes here
Padding(
padding: const EdgeInsets.all(defaultPadding),
child: ElevatedButton.icon(
onPressed: () async {
print('setting job location');
widget.setJobAddess('TEXT');
Navigator.pop(context);
},
icon: Icon(Icons.home),
label: const Text("Set job location"),
style: ElevatedButton.styleFrom(
backgroundColor: secondaryColor10LightTheme,
foregroundColor: textColorLightTheme,
elevation: 0,
fixedSize: const Size(double.infinity, 40),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
),
),
I got the following error::
════════ Exception caught by widgets library ═══════════════════════════════════
The following NoSuchMethodError was thrown building Builder:
Closure call with mismatched arguments: function '_CreateUpdateJobViewState._setJobAddress'
Receiver: Closure: (dynamic) => void from Function '_setJobAddress@43263735':.
Tried calling: _CreateUpdateJobViewState._setJobAddress()
Found: _CreateUpdateJobViewState._setJobAddress(dynamic) => void
The relevant error-causing widget was
MaterialApp
lib/main.dart:20
When the exception was thrown, this was the stack
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
#1 _objectNoSuchMethod (dart:core-patch/object_patch.dart:85:9)
#2 _SearchLocationScreenState.initState
package:ijob_clone_app/…/location/location_search_screen.dart:26
#3 StatefulElement._firstBuild
package:flutter/…/widgets/framework.dart:5015
#4 ComponentElement.mount
package:flutter/…/widgets/framework.dart:4853
... Normal element mounting (275 frames)
#279 Element.inflateWidget
package:flutter/…/widgets/framework.dart:3863
#280 MultiChildRenderObjectElement.inflateWidget
package:flutter/…/widgets/framework.dart:6435
#281 Element.updateChild
package:flutter/…/widgets/framework.dart:3592
#282 RenderObjectElement.updateChildren
package:flutter/…/widgets/framework.dart:5964
#283 MultiChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:6460
#284 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#285 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#286 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#287 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#288 StatefulElement.update
package:flutter/…/widgets/framework.dart:5082
#289 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#290 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#291 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#292 ProxyElement.update
package:flutter/…/widgets/framework.dart:5228
#293 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#294 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#295 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#296 ProxyElement.update
package:flutter/…/widgets/framework.dart:5228
#297 _InheritedNotifierElement.update
package:flutter/…/widgets/inherited_notifier.dart:107
#298 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#299 SingleChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:6307
#300 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#301 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#302 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#303 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#304 StatefulElement.update
package:flutter/…/widgets/framework.dart:5082
#305 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#306 SingleChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:6307
#307 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#308 SingleChildRenderObjectElement.update
package:flutter/…/widgets/framework.dart:6307
#309 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#310 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#311 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#312 ProxyElement.update
package:flutter/…/widgets/framework.dart:5228
#313 Element.updateChild
package:flutter/…/widgets/framework.dart:3570
#314 ComponentElement.performRebuild
package:flutter/…/widgets/framework.dart:4904
#315 StatefulElement.performRebuild
package:flutter/…/widgets/framework.dart:5050
#316 Element.rebuild
package:flutter/…/widgets/framework.dart:4604
#317 BuildOwner.buildScope
package:flutter/…/widgets/framework.dart:2667
#318 WidgetsBinding.drawFrame
package:flutter/…/widgets/binding.dart:882
#319 RendererBinding._handlePersistentFrameCallback
package:flutter/…/rendering/binding.dart:378
#320 SchedulerBinding._invokeFrameCallback
package:flutter/…/scheduler/binding.dart:1175
#321 SchedulerBinding.handleDrawFrame
package:flutter/…/scheduler/binding.dart:1104
#322 SchedulerBinding._handleDrawFrame
package:flutter/…/scheduler/binding.dart:1015
#323 _invoke (dart:ui/hooks.dart:148:13)
#324 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#325 _drawFrame (dart:ui/hooks.dart:115:31)
════════════════════════════════════════════════════════════════════════════════
D/EGL_emulation(15747): app_time_stats: avg=25.04ms min=14.73ms max=497.29ms count=59
D/TrafficStats(15747): tagSocket(145) with statsTag=0xffffffff, statsUid=-1
D/TrafficStats(15747): tagSocket(121) with statsTag=0xffffffff, statsUid=-1
CodePudding user response:
with this you can pass it and get it from the constructor.
class SearchLocationScreen extends StatefulWidget {
const SearchLocationScreen(this.setJobAddess,{Key? key, }) : super(key: key);
final setJobAddess;
@override
State<SearchLocationScreen> createState() => _SearchLocationScreenState();
}
class _SearchLocationScreenState extends State<SearchLocationScreen> {
/*now you can use call it with like this */
@override
void initState() {
widget.setJobAddess();
}
List<AutocompletePrediction> placePredictions = [];
// your other code
the StatefulWidget
gives you the possibility to get properties from the constructor, and to access that property from the State
class you need just to use widget.setJobAddess();
CodePudding user response:
this is what worked for me
TextButton(
onPressed: () => {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchLocationScreen(
setJobAddress: _setJobAddress)))
},
child: Text(_jobAddress),
),
child widget::
class SearchLocationScreen extends StatefulWidget {
final Function setJobAddress;
const SearchLocationScreen({Key? key, required this.setJobAddress})
: super(key: key);
@override
State<SearchLocationScreen> createState() => _SearchLocationScreenState();
}
class _SearchLocationScreenState extends State<SearchLocationScreen> {
List<AutocompletePrediction> placePredictions = [];
@override
...
Expanded(
child: ListView.builder(
itemCount: placePredictions.length,
itemBuilder: ((context, index) => LocationListTile(
press: () {
widget
.setJobAddress(placePredictions[index].description);
Navigator.pop(context);
},
location: placePredictions[index].description!,
))),
),