I have this simple code in my main.dart which gets the user's current geolocation what I want to do is to create a separate file like get_geolocation.dart and then call it back in my main.dart just to make my main.dart file cleaner, less code in it and more organized. Here's my main.dart code:
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Position? _position;
void _getCurrentLocation() async {
Position position = await _determinePosition();
setState(() {
_position = position;
});
}
Future<Position> _determinePosition() async {
LocationPermission permission;
permission = await Geolocator.checkPermission();
if(permission== LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if(permission == LocationPermission.denied){
return Future.error('Location Permissions are denied');
}
}
return await Geolocator.getCurrentPosition();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('geolocator'),
centerTitle: true,
),
body: Center(
child: _position != null
? Text('Current position: ' _position.toString())
: Text('No Location Data'),
),
floatingActionButton: FloatingActionButton(
onPressed: _getCurrentLocation,
tooltip: 'increment',
child: const Icon(Icons.add),
),
);
}
}
CodePudding user response:
Using underscore in method names, class and variables makes it private. so you can only access it where it defined. In your code, it's in main.dart. Here I have removed underscores in get_geolocation.dart.
Here I did just like @Omi shah told in comments.
- Extract the widget and moved in to a new file.
- import the package name.
Change as you want.
main.dart
import 'package:flutter/material.dart';
// import 'package:geolocator/geolocator.dart';
import 'get_geolocation.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
get_geolocation.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Position? _position;
void getCurrentLocation() async {
Position position = await determinePosition();
setState(() {
_position = position;
});
}
Future<Position> determinePosition() async {
LocationPermission permission;
permission = await Geolocator.checkPermission();
if(permission== LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if(permission == LocationPermission.denied){
return Future.error('Location Permissions are denied');
}
}
return await Geolocator.getCurrentPosition();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('geolocator'),
centerTitle: true,
),
body: Center(
child: _position != null
? Text('Current position: ' _position.toString())
: Text('No Location Data'),
),
floatingActionButton: FloatingActionButton(
onPressed: _getCurrentLocation,
tooltip: 'increment',
child: const Icon(Icons.add),
),
);
}
}
CodePudding user response:
You could create a class to keep your methods and interfaces to geolocation services.
file: lib/src/utils/location_controller.dart
class LocationController {
LocationController();
// This way you create only one instance of Geolocator
// instead of creating a new instance every time the method is called
late final geolocator = Geolocator();
Future<Position> get myPosition async {
// Place additional logic
return await geolocator.getCurrentPosition();
}
}
Import this class in any widget:
class _HomePageState extends State<HomePage> {
late final locationController = LocationController();
Position? _position;
void _getCurrentLocation() async {
final position = await locationController.myPosition;
setState(() {
_position = position;
});
}
If this "controller" becomes heavy to initialize, you might want to instantiate it in your main and pass down the tree as a parameter or use another method such as Provider.
You can create your apps in flutter using the skeleton template:
flutter create -t skeleton my_app
It will give some ideia on how to structure your files and lots of best practices.