ChatGPT has been everywhere lately. Be it on Twitter, YouTube, or the Blogosphere, people are talking about it all the time. And given the crazy stuff ChatGPT can do, I would so, all the buzz around it is only natural.
I however have only been watching it from afar, until this morning, when I finally thought of giving it a few hours and see how it goes.
Not to mention, it is the most accurate chatbot I have ever talked to. I began with some basic stuff like generating blog posts with ChatGPT and asking a few random questions here and there.
But the real fun began when I thought of asking it to create a Flutter App for me!
Creating a Flutter App using ChatGPT
Functionality-wise, the requirement was quite simple. My main intention was to see whether ChatGPT can give me the complete code and instructions, if any, that I can just copy-paste to VSCode and run.
Without writing a single line of code!
I thought of asking it to create a simple RunningApp in Flutter, that can track the distance covered and the time taken when on a run.
My first ChatGPT prompt was this:
Write me a simple running app in Flutter
ChatGPT, almost immediately, threw this bit of code for me:
import 'package:flutter/material.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Running App',
home: StopwatchPage(),
);
}
}
class StopwatchPage extends StatefulWidget {
@override
_StopwatchPageState createState() => _StopwatchPageState();
}
class _StopwatchPageState extends State<StopwatchPage> {
Stopwatch _stopwatch = Stopwatch();
Timer _timer;
Duration _duration = Duration();
void _startTimer() {
setState(() {
_stopwatch.start();
_timer = Timer.periodic(Duration(milliseconds: 100), _updateTimer);
});
}
void _stopTimer() {
setState(() {
_stopwatch.stop();
_timer.cancel();
});
}
void _resetTimer() {
setState(() {
_stopwatch.reset();
_duration = Duration();
});
}
void _updateTimer(Timer timer) {
setState(() {
_duration = _stopwatch.elapsed;
});
}
String _formatDuration(Duration duration) {
String twoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
String twoDigitMilliseconds =
twoDigits(duration.inMilliseconds.remainder(100));
return "$twoDigitMinutes:$twoDigitSeconds.$twoDigitMilliseconds";
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Running App'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Distance: 0 km',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
Text(
'Time: ${_formatDuration(_duration)}',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
onPressed: _startTimer,
child: Icon(Icons.play_arrow),
),
SizedBox(width: 20),
FloatingActionButton(
onPressed: _stopTimer,
child: Icon(Icons.stop),
),
SizedBox(width: 20),
FloatingActionButton(
onPressed: _resetTimer,
child: Icon(Icons.replay),
),
],
),
],
),
),
);
}
}
Below the code, ChatGPT also gave me some basic details about how the code works. You can see that bit, below:
This code creates a simple UI with two text widgets for displaying the distance and time, and three floating action buttons for starting, stopping, and resetting the stopwatch.
The stopwatch is implemented using a Stopwatch object and a Timer object to update the UI every 100 milliseconds. The distance is currently hard-coded to 0 km, but you can replace it with your own implementation for tracking distance based on location data.
That's it! You should now have a basic running app in Flutter that tracks your running time.
On the side, I had already created a fresh Flutter project. All I had to now do was, replace the existing code in the lib/main.dart file with what ChatGPT has given me and see if it works.
I copy-pasted the above-mentioned code, and saved the main.dart file and hit run.
Bamm!! Error!!
On line 22, the Timer _timer; value threw the following error:
Non-nullable instance field '_timer' must be initialized.
Thankfully, it was a simple problem that I solved by updating the variable declaration as in the code below:
late Timer _timer;
That’s the only code I had to write. The app ran smoothly on the simulator and did what it was supposed to, theoretically.
Damn!! This is for real!!
A flutter app completely written by a chatbot that is smart!
Upgrading the RunningApp using ChatGPT
If you noticed the description given by ChatGPT, after it gave me the code, you will notice that it says that the distance is hard-coded to 0.
I wanted to change that and wanted an app that also tracks the user’s location when tracking the time.
So, I asked ChatGPT the following:
Write me a simple running app with geolocation in Flutter
ChatGPT obliged and gave me the following code and some instructions but not before breaking or sleeping a few times.
The instructions by ChatGPT, followed by the updated code below:
First, make sure to add the location and flutter_map packages to your pubspec.yaml file.
Then, create a new Flutter project and open the main.dart file. Replace the code with the following:
import 'dart:async';
import 'dart:math' show sin, cos, sqrt, atan2, pi;
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:location/location.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Running App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Running App'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Completer<GoogleMapController> _controller = Completer();
Location _location = Location();
Set<Polyline> _polylines = {};
List<LatLng> _points = [];
Timer? _timer;
Duration _duration = Duration.zero;
static final CameraPosition _kInitialPosition = CameraPosition(
target: LatLng(37.42796133580664, -122.085749655962),
zoom: 16.0,
);
@override
void initState() {
super.initState();
_location.onLocationChanged.listen((LocationData currentLocation) {
if (_points.isNotEmpty) {
LatLng previousPoint = _points.last;
LatLng currentPoint = LatLng(currentLocation.latitude!, currentLocation.longitude!);
if (_getDistanceBetweenPoints(previousPoint, currentPoint) > 10) {
_points.add(currentPoint);
_updatePolyline();
}
} else {
_points.add(LatLng(currentLocation.latitude!, currentLocation.longitude!));
_updatePolyline();
}
});
}
void _updatePolyline() {
Polyline polyline = Polyline(
polylineId: PolylineId('running_path'),
color: Colors.blue,
points: _points,
);
setState(() {
_polylines.add(polyline);
});
}
void _startTimer() {
if (_timer == null) {
_timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {
setState(() {
_duration = _duration + Duration(seconds: 1);
});
});
}
}
void _stopTimer() {
if (_timer != null) {
_timer!.cancel();
_timer = null;
}
}
void _resetTimer() {
setState(() {
_duration = Duration.zero;
_stopTimer();
_points.clear();
_polylines.clear();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _kInitialPosition,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
polylines: _polylines,
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () {
_startTimer();
},
child: Icon(Icons.play_arrow),
),
SizedBox(height: 16.0),
FloatingActionButton(
onPressed: (){},
child: Icon(Icons.stop),
backgroundColor: Colors.red,
),
SizedBox(height: 16.0),
FloatingActionButton(
onPressed: () {
_resetTimer();
},
child: Icon(Icons.refresh),
),
],
),
bottomNavigationBar: BottomAppBar(
child: Container(
height: 48.0,
child: Center(
child: Text(
'${_duration.inMinutes}:${(_duration.inSeconds % 60).toString().padLeft(2, '0')}',
style: TextStyle(fontSize: 24.0),
),
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
double _getDistanceBetweenPoints(LatLng p1, LatLng p2) {
const double radius = 6371; // Earth's radius in km
double lat1 = p1.latitude * pi / 180;
double lon1 = p1.longitude * pi / 180;
double lat2 = p2.latitude * pi / 180;
double lon2 = p2.longitude * pi / 180;
double dLat = lat2 - lat1;
double dLon = lon2 - lon1;
double a = sin(dLat / 2) * sin(dLat / 2) + cos(lat1) * cos(lat2) * sin(dLon / 2) * sin(dLon / 2);
double c = 2 * atan2(sqrt(a), sqrt(1 - a));
double distance = radius * c * 1000; // Convert to meters
return distance;
}
}
You can download the app created by ChatGPT from here.