-
DISCLAIMER : This repository is not an official outcome of London AppBrewery Team
-
This repository is made to help new students get through AppBrewery Flutter Course
-
This repository contains notes for only coding (project) sections and explains what has changed and what's the difference.
-
If something is not covered here, start a dicussion, not an issue! I will try to add it then.
-
Use latest verions of required
packages
andplugins
, find them on pub.dev
1. Terminology
3. Resources
- You will often come across
deprecated
stuff, where it says This isdeprecated
. This means it's not recommended to use it anymore in your projects. You should avoid it and use alternatives.
-
Null safety is not your enemy! It's there you help you so you don't accidentally make something null and crash your app.
-
Dart has
sound null safety
. Basically, if you're writng any code that compiler thinks might end up beingnull
, it will notify you right away! Isn't that cool? -
Read more : Sound Null Safety, Understanding Null Safety, Null Safety in Flutter
-
Use latest
Flutter SDK
, currently I am using2.2
instable channel
- To upgrade old one, run
flutter upgrade
in yourTerminal / Command Prompt (cmd)
- To upgrade old one, run
-
There are couple of things that can cause this, I'll keep adding them in future! For now I have these solutions,
-
Just run
flutter doctor --android-licenses
-
Normally, this does the job. If it doesn't, go ahead.
-
Open Settings panel by,
-
File > Settings
(Windows and Linux) -
Android Studio > Preferences
(Mac)
-
-
Then navigate to,
Appearance & Behavior > System Settings > Android SDK
-
Select the
SDK Tools
Tab -
Select
Android SDK Command Line Tools
and clickApply
-
A dialog will pop up and ask you if you want to install these.
Click Yes/OK and let it install, after that, close
Android Studio
andrestart
it.
-
-
When I first encountered this issue, I thought there must be something wrong with just this particular update.
-
I searched it online, posted on reddit, twitter, but found nothing.
-
Later on, I got to know that
New > Package
andNew > Directory (Folder)
options have now merged! -
So, to create a new
package
or just afolder
, simply useNew > Directory
option.
1. Try out Null Safety on DartPad
2. Read Updated Flutter Docs
3. Watch and Follow Flutter's Official Youtube Channel
- To learn more about Null Safety and staying updated in general.
-
You right clicked on
res
folder but didn't findImage Asset
? Don't worry Follow these steps,-
Right click on
android
folder and a pop-up menu wiil open up.From that, select
Flutter > Open Android Module in Android Studio
If this doesn't work for you then follow these steps,
1. Close current project by pressing
File > Close Project
2. Now you will have the first screen of Android Studio.
3. Press
Open an Existing Project
, thenOpen File or Project
dialog will open.4. Here, navigate to your Flutter project in which, you want to add
Image Asset
5. Expand that and you will find
android
folder. Select that and pressOK
-
-
Both ways should open Android Part of your Flutter Project in
Android Studio
. -
Now, at bottom right, if it's running any
gradle
processes, let it run. Don't interrupt! However, if you close it, it'll rebuild everything when you reopen it. So, no need to worry! -
After that long build process completes, you can find
Image Asset
option when you click onres
folder, Yay! -
Add assets and again,
File > Close Project
,Open an Existing Project
and this time, select your Flutter Project and continue!
FlatButton
isdeprecated
, so useTextButton
instead.
-
Getting a LOOONNNGGG error when trying to use
audioplayers
plugin?-
All you need to do is open
android > build.gradle
(Project Levelgradle
file) -
Inside
buildscript {}
, you'll findext.kotlin_version
(Line 2 in file) -
Replace whatever version it is with Latest Stable Kotlin Version
-
As of July 23, 2021 it is,
ext.kotlin_version = '1.5.21'
-
Now, re-install the app. If it's already running, press Stop then press Run (Play) again.
-
-
FlatButton
isdeprecated
, so useTextButton
instead.-
HOWEVER, for this module, you won't be adding any
child
toFlatButton
, this will throw an error becausechild
is arequired
property. -
So, for Xylopone Keys, use
MaterialButton
instead ofFlatButton
-
-
Due to
null safety
, all variables in a class must have a value assigned, when created. If not, they must be declaredNullable
intentionally. This rule also applies toStateless
andStateful
widgets. On top of that, in classes extendingStatelessWidget
, all variables must be declaredfinal
-
So, make your
Question
class like this,class Question { String questionText; bool questionAnswer; Question(this.questionText, this.questionAnswer); // If you want named parameters // Question({required this.questionText, required this.questionAnswer}); }
-
@required
is replaced by justrequired
(Without @ sign) -
Here, the Keyword
this
points to current context, which happens to beQuestion
class.
-
-
FlatButton
isdeprecated
, so useTextButton
instead.
-
@required
is replaced by justrequired
(Without @ sign) -
So, while making
ReusableCard
, lesson shows you can skip usingcardChild
property, but that isn't possible, due tonull safety
-
This part is tricky, because now you can't have null arguments anymore.
-
So, you must have to intentionally make it
Nullable
, by adding?
to it, like this,class ReusableCard extends StatelessWidget { final Color colour; final Widget? cardChild; ReusableCard({required this.colour, this.cardChild}); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: colour, ), child: child, ); } }
-
Use it like
ReusabledCard(color: Colors.amber)
and your app won't crash.
-
-
But, it's not same for
IconContent
,Icon
can havenull
value, butText
can't!class IconContent extends StatelessWidget { final IconData? icon; final String? label; IconContent({this.icon, this.label}); @override Widget build(BuildContext context) { return Column( children: [ Icon(icon), Text(label ?? ''), ], ); } }
-
So using
??
operator, you need to check if label isnull
or not, if it is, then you must provide aString
value to it. Here, I provided an empty String. -
Even if you don't pass any arguments like
IconContent()
, your app won't crash.
-
-
According to Lesson 129,
ReusableCard
now has a parameter namedonPress
, to get it working, use this,class ReusableCard extends StatelessWidget { final Color colour; final Widget? cardChild; final void Function()? onPress; ReusableCard({required this.colour, this.cardChild, this.onPress}); @override Widget build(BuildContext context) { return GestureDetector( onTap: onPress, child: Container( decoration: BoxDecoration( color: colour, ), child: child, ), ); } }
- Because
GestureDetector
'sonTap
propery wantsvoid Function()?
as argument.
- Because
-
In Lesson 128,
_InputPageState
has a new variable which haven't been initialized. As I already told you, you must initialize them or make themNullable
.class _InputPageState extends State<InputPage> { Gender? selectedGender; }
- Here, making it
Nullable
will do the job. Rest of the code will work perfectly fine.
- Here, making it
-
When running this app on a Physical Device, you will need Internet Permisson because app is sending a
request
toAPI
-
Android
: For this, openAndroidManifest.xml
by navigating to,android > app > src > main > AndroidManifest.xml
and add the following line,
<uses-permission android:name="android.permission.INTERNET"/>
Keep the existing location permissions and add this above/below them. Add it under
manifest
tag, like this,<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="detaineddeveloper.example.clima"> <uses-permission android:name="android.permission.ACCESSS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESSS_FINE_LOCATION"/> <!--Keep the existing location permisions above (whichever you have added previously)--> <uses-permission android:name="android.permission.INTERNET"/> <application android:label="clima" android:icon="@mipmap/ic_launcher"> . . . </application> </manifest>
-
iOS
: I don't know, I don't have aniOS
device!
-