Reputation: 542
How to pass a function parameter in a Flutter object (function pointer in C++)? All samples seem to be outdated.
I have a main page with a BottomNavigationBar and it works with 4 stateful widgets. It changes the body widget to each of the four widgets as the tabs are pushed. _currentPage
body: Padding(
padding: const EdgeInsets.all(10.0),
child: SingleChildScrollView(child: _currentPage),
I need some way to signal from the child widget to the parent that the settings have been saved so that it programmatically moves back to the home tab.
I guess the way to do this is to create a constructor in the stateful widget with a parameter that sets a member called.
final VoidCallBack goToHome();
This code was suggested on Stack Overflow here
I want to add a final VoidCallBack goToHome(); to my child stateful widget below. The parent has member widgets already created in the class parameters.
This was suggested on Stack Overflow here
Below is the code sample that I want to add a function callback member and have the constructor set it.
My full project code is located on GitHub here (subject to change)
// parent has this function
void goToHome() {
_currentIndex = 0;
_currentPage = _page1;
setState(() {});
}
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:geolocator/geolocator.dart';
class GPSLocation extends StatefulWidget {
// add constructor here
// add member VoidCallBack goToHome();
@override
_GPSLocationState createState() => _GPSLocationState();
}
class _GPSLocationState extends State<GPSLocation> {
Geolocator geoLocator = Geolocator();
bool _initPerformed = false;
String _message = "Please wait for GPS";
@override
void initState() {
initGps();
super.initState();
}
@override
void dispose() {
super.dispose();
}
void initGps() async {
if (!_initPerformed) {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
_message = 'Location permissions are denied';
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
_message =
'Location permissions are permanently denied, we cannot request permissions.';
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
} // no finished with init of gps.
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("cityName", "GPS Generated");
prefs.setDouble("lat", position.latitude);
prefs.setDouble("lng", position.longitude);
_message = 'GPS is set to ${position.latitude}, ${position.longitude}';
setState(() {});
// this is the magic...
// call the parent's function here
goToHome();
}
var controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Container(
child: Text("$_message"),
);
}
}
Upvotes: 1
Views: 2381
Reputation: 542
With some trial and error and google.. I got this to work.
In the beginning the syntax to create a callback function is this GPSLocation({required this.goToHome});// passed named variable to avoid null final VoidCallback goToHome; // member decl
called later with this code widget.goToHome();
Here is the code:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:geolocator/geolocator.dart';
class GPSLocation extends StatefulWidget {
GPSLocation({required this.goToHome});
final VoidCallback goToHome;
@override
_GPSLocationState createState() => _GPSLocationState();
}
class _GPSLocationState extends State<GPSLocation> {
Geolocator geoLocator = Geolocator();
bool _initPerformed = false;
String _message = "Please wait for GPS";
@override
void initState() {
initGps();
super.initState();
}
@override
void dispose() {
super.dispose();
}
void initGps() async {
if (!_initPerformed) {
bool serviceEnabled;
LocationPermission permission;
// Test if location services are enabled.
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
// Location services are not enabled don't continue
// accessing the position and request users of the
// App to enable the location services.
return Future.error('Location services are disabled.');
}
permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
// Permissions are denied, next time you could try
// requesting permissions again (this is also where
// Android's shouldShowRequestPermissionRationale
// returned true. According to Android guidelines
// your App should show an explanatory UI now.
_message = 'Location permissions are denied';
}
}
if (permission == LocationPermission.deniedForever) {
// Permissions are denied forever, handle appropriately.
_message =
'Location permissions are permanently denied, we cannot request permissions.';
}
// When we reach here, permissions are granted and we can
// continue accessing the position of the device.
} // no finished with init of gps.
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.best);
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("cityName", "GPS Generated");
prefs.setDouble("lat", position.latitude);
prefs.setDouble("lng", position.longitude);
_message = 'GPS is set to ${position.latitude}, ${position.longitude}';
setState(() {});
widget.goToHome();
}
var controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Container(
child: Text("$_message"),
);
}
}
Upvotes: 3