WIDGETS
BEGINNER LEVEL FLUTTER APPS
Flutter Health Status
Run this command to check Flutter Status on your device
flutter doctor
Run this command to check available devices for Flutter
flutter devices
Run this command to upgrade Flutter
flutter upgrade
Run this command to configure Flutter
flutter config
Run this command to check Flutter Channel
flutter channel
Run this command to switch to Flutter Channel Beta, likewise you can switch back to stable
flutter channel beta
Run this command to Repair Pub Cache
flutter pub cache repair
Create App
Run this command to create an app, just replace app_name
with your desired app name but without spaces and special characters except Underscore(_)
flutter create app_name
Specify Package Name
Create your Flutter app with this command to customize your app’s package name; Package name from the below command will be com.company.app_name
You can change it accordingly
flutter create --org com.company app_name
Create Command for Release
flutter create --androidx -t app --org com.company -a kotlin -i swift app_name
Run App
Run this command to run a Flutter Project
flutter run
Run this command to check runner logs while running
flutter run -v
Run this command to run the project on specific device when there are muliple devices available replace device_ID
with your device ID Sample: flutter run -d chrome
to run flutter web project on Chrome Browser
flutter run -d device_ID
Run this command to run the flutter web project on specific port of localhost Sample: flutter run -d chrome --web-hostname localhost --web-port 8080
to run flutter web project on port localhost:8080
on Web Browser
flutter run -d chrome --web-hostname localhost --web-port [port_number]
Signing App
Step 1
Create a keystore If you have an existing keystore, skip to the next step. If not, create one by running the following at the command line:
./keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
OR Run this if get error
.\keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
Note: Keep this file private; do not check it into public source control. Note: keytool may not be in your path. It is part of the Java JDK
, which is installed as part of Android Studio. For the concrete path, run flutter doctor -v
and see the path printed after Java binary at:
and then use that fully qualified path replacing java with keytool.
Step 2
Reference the keystore from the app Create a file named key.properties<Project>/android/key.properties
that contains a reference to your keystore: Add these lines in /android/key.properties
storePassword= password from previous step keyPassword= password from previous step keyAlias= key storeFile= location of the key store file, e.g. /Users/username/key.jks
Step 3
Add these lines above android{ } (near line 16) in /android/app/build.gradle
def keystorePropertiesFile = rootProject.file("key.properties") def keystoreProperties = new Properties() keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
Add these lines in android{ } in /android/app/build.gradle
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
Creating a plugin/dependency in Flutter
Step 1
Create a package first, using the following command:
flutter create --template-plugin --org --com.example --template= plugin --platform= android, ios, -a java -i objc plugin_name
Note: you can use the any language you prefer for android and ios. To add web support in your plugin use the following command:
flutter create --template=plugin --platform=web .
Step 2
Add the plugin code in plugin_name.dart
and also arrange your pubspec.yaml
and add following fields:
name: name of your plugin project
description: description of the plugin project
version: version of the package to be hosted on pub.dev
author: name of the author
homepage: link of the package's homepage
documentation: link of the plugin documentation
publish_to: specify where to publish the plugin it should be a link, if you do not want to publish it then place none instead of a link
environment:
sdk:
flutter:
dependencies:
// list any dependencies used by the plugin
dev_dependencies:
// list any dev dependencies used by the plugin
Step 3
Publishing the plugin package:
flutter publish --dry-run # this command will help you verify that everything is as intended
flutter pub publish # it will publish the plugin on pub.dev
Now, you have successfully published your plugin. You can check it by using the following link:
https://pub.dev/packages/YOUR_PACKAGE_NAME
Build App
Run this command to build Android .apk file
flutter build apk
Run this command to build Android .apk file in release mode
flutter build apk --release
Run this command to build Web root folder in release mode
flutter build web --release
Generate App Bundles
flutter build appbundle --target-platform android-arm,android-arm64,android-x64
Split the APKs per ABI
Run this command to reduce the APK Size to the minimum
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi
Flutter Build Web Release
Run this command to build web release for Flutter Web App
flutter build web --release --web-renderer html
Basic App
This is a very basic beginner level app that is showing two List Tiles in its body. To run this code copy and paste it in lib/main.dart
// Importing Material Library import 'package:flutter/material.dart'; // Main Function of this App // We will call runApp that is a built-in function that will run the App void main() => runApp( // Material App is the outer most Parent Widget that will wrap the child widgets MaterialApp( // To remove the Debug Tag from the App debugShowCheckedModeBanner: false, // Setting App Theme data theme: ThemeData( primarySwatch: Colors.red,), // Title is the title of the app title: 'Messenger', // Home widget of Material App home: Scaffold( // App Bar of the App appBar: AppBar( // Title of the App Bar title: Text('Inbox'), // This is the leading icon on the App Bar leading: Icon(Icons.menu_open), // These are action icon(s) on the App Bar actions: [ // padding for wraping with some space Padding( // padding: EdgeInsets.all(8.0), // Padding value set to 8.0 on all sides padding: EdgeInsets.only(right: 15.0), // Padding value set to 15.0 on right side child: Icon(Icons.create_sharp), // Added a favourite icon ), ], ), // This is the body of Scafold body: Column( // Alignment across main (Vertical) Axis mainAxisAlignment: MainAxisAlignment.start, // Alignment across cross (Horizontal) Axis crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // For setting some space around Card Padding( padding: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 0.0), // Creating Card child: Card( elevation: 5.0, // Setting List Tile child: ListTile( // Setting Leading Icon leading: Icon( Icons.account_circle, // Setting Size of the Icon size: 40.0, // Setting Icon Color color: Colors.amber, ), // Setting Title of the List Tile title: Text('Usama Sarwar'), // Setting Sub-Title of the List Tile subtitle: Text('Happy Birthday to you 🎂'), // Setting Trailing Icon trailing: Icon( Icons.send, color: Colors.amberAccent),),),), // For setting some space around Card Padding( padding: const EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 0.0), // Creating Card child: Card( elevation: 5.0, // Setting List Tile child: ListTile( // Setting Leading Icon leading: Icon( Icons.account_circle, // Setting Size of the Icon size: 40.0, // Setting Icon Color color: Colors.grey[700], ), // Setting Title of the List Tile title: Text('Ayesha Ali'), // Setting Sub-Title of the List Tile subtitle: Text('Let\'s meet at 10\'O Clock ⌚'), // Setting Trailing Icon trailing: Icon( Icons.send, color: Colors.grey[700],),),),),],),),),);
Stateless Widget
In Stateless widget the state of app can’t change. Here is an example of a counter app in which you can observe the chnaging value in the console but on UI it will not render. To render the value accourdingly you will have to use Stateful Widget that is the next example.
// Importing Material Library import 'package:flutter/material.dart'; // Main Function of this App // We will call runApp that is a built-in function that will run the App void main() => runApp(MyApp()); class MyApp extends StatelessWidget { // Initilized a variable static int number = 1; // Function for performing task void increment() { number++; } @override Widget build(BuildContext context) { return // Material App is the outer most Parent Widget that will wrap the child widgets MaterialApp( // To remove the Debug Tag from the App debugShowCheckedModeBanner: false, // Setting App Theme data theme: ThemeData( primarySwatch: Colors.red, ), // Title is the title of the app title: 'Stateless Widget', // Home widget of Material App home: Scaffold( // App Bar of the App appBar: AppBar( // Title of the App Bar title: Text('Stateless Widget Example'), // These are action icon(s) on the App Bar ), // Body of Scafold body: Center( // Display a text in the center // This is how to display a text child: Text( // Concatination of a String with some variable 'Number: $number', // However this will not update // Styling text style: TextStyle( // Setting fontSize fontSize: 25.0,),),), // FloatingActionButton Added floatingActionButton: FloatingActionButton( // Setting Icon child: Icon(Icons.add), // Setting action on button when it is pressed onPressed: () { // Funtion for the incrementation increment(); // To check the value of number on console print('Number: $number'); },),),);}}
Stateful Widget
In Stateful Widget, the state of the app can be changed. It renders everytime whenver it detectects the change in the value of some variable. Here is the sample code.
// Importing Material Library import 'package:flutter/material.dart'; // Main Function of this App // We will call runApp that is a built-in function that will run the App void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { // Initilized a variable static int number = 1; // Increment Function void increment() { // Calling SetState will render the User Interface and update it accordingly setState(() { number++; });} @override Widget build(BuildContext context) { return // Material App is the outer most Parent Widget that will wrap the child widgets MaterialApp( // To remove the Debug Tag from the App debugShowCheckedModeBanner: false, // Setting App Theme data theme: ThemeData( primarySwatch: Colors.red, ), // Title is the title of the app title: 'Stateful Widget', // Home widget of Material App home: Scaffold( // App Bar of the App appBar: AppBar( // Title of the App Bar title: Text('Stateful Widget Example'), // These are action icon(s) on the App Bar ), // Body of Scafold body: Center( // Display a text in the center // This is how to display a text child: Text( // Concatination of a String with some variable 'Number: $number', // However this will not update // Styling text style: TextStyle( // Setting fontSize fontSize: 25.0, ),),), // FloatingActionButton Added floatingActionButton: FloatingActionButton( // Setting Icon child: Icon(Icons.add), // Setting action on button when it is pressed onPressed: () { // Funtion for the incrementation increment(); // To check the value of number on console print('Number: $number');},),),);}}
App Navigation
Navigator in Flutter application manages the routes and screen navigation. According to official docs: The navigator manages a stack of Route objects and provides methods for managing the stack, like Navigator.push and Navigator.pop.
import 'package:flutter/material.dart'; void main() => runApp(Home()); class Home extends StatelessWidget { // Home Widget @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Routing Sample App', // Initial Route when App Starts initialRoute: '/', // Named Routes for all widgets in App routes: { // We can use any string instead of '\' '/': (context) => HomeScreen(), // Main Screen Route '/S1': (context) => Screen1(), // This is child screen of Home Screen '/S1/S2': (context) => Screen2(), // This is child screen of Screen 1 },);}} // Home Screen Widget class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Home Screen'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('This is Home Screen'), RaisedButton( child: Text('Screen 1'), // This will navigate to named route '/S1' that is Screen 1 onPressed: () => Navigator.pushNamed(context, '/S1'), ),],),),);}} // Screen 1 Widget class Screen1 extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Screen 1'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('This is Screen 1'), RaisedButton( child: Text('Home Screen'), // This will navigate to the parent screen from where it reached here onPressed: () => Navigator.pop(context), ), RaisedButton( child: Text('Screen 2'), // This will navigate to named route '/S1/S2' that is Screen 2 onPressed: () => Navigator.pushNamed(context, '/S1/S2'), ),],),),);}} // Screen 2 Widget class Screen2 extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Screen 2'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('This is Screen 2'), RaisedButton( child: Text('Home Screen'), // This will navigate to named route '/' that is Home Screen onPressed: () => Navigator.pushNamed(context, '/'), ), RaisedButton( child: Text('Screen 1'), // This will navigate to the parent screen from where it reached here onPressed: () => Navigator.pop(context), ),],),),);}}
ListView Builder
import 'package:flutter/material.dart'; void main() => runApp(Home()); // List of items List<String> list = ['Item 0']; // Variable for incrementing value int num = 1; class Home extends StatelessWidget { // Home Widget @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'ListView Builder', // Initial Route when App Starts initialRoute: '/', // Named Routes for all widgets in App routes: { // We can use any string instead of '\' '/': (context) => HomeScreen(), // Main Screen Route },);}} class HomeScreen extends StatefulWidget { @override _HomeScreenState createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> { // Function for adding value into the list void addItem() { setState(() { list.add('Item ' + '${num.toString()}'); }); print(list); // For console logs num++; } // Function for deleting value from the list void delItem(int index) { setState(() { list.removeAt(index); }); print(list); // For console logs } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.red, title: Text('ListView Builder'), actions: [ // Icon Button to add item into the list IconButton( icon: Icon(Icons.add), onPressed: () { addItem(); },),],), body: ListView.builder( // .length will automatically determine the size of list itemCount: list.length, itemBuilder: (context, index) { return Padding( padding: EdgeInsets.fromLTRB(8.0, 5.0, 8.0, 0.0), child: Card( elevation: 5.0, child: ListTile( // To show Snackbar onTap: () { Scaffold.of(context).showSnackBar( SnackBar(content: Text('You tapped on ${list[index]}'))); }, // Smile, because it's good for health leading: Icon( Icons.insert_emoticon, color: Colors.amber, size: 40, ), // Icon Butoon to delete value at certain index trailing: IconButton( icon: Icon( Icons.delete, color: Colors.red, ), onPressed: () { delItem(index); },), // Setting title to ListTile title: Text( 'Title of ${list[index]}', ), // Setting subtitle to ListTile subtitle: Text('Subtitle of ${list[index]}'), ), ), ); }, ), // Floating Action Button to add values into the list floatingActionButton: FloatingActionButton( backgroundColor: Colors.red, child: Icon(Icons.add), onPressed: addItem, ),);}}
Status Bar
// Import Services Package import 'package:flutter/services.dart'; void main() { // Hide Status bar and Bottom Navigation Bar SystemChrome.setEnabledSystemUIOverlays([]); }
Lock Orientation
// Import library import 'package:flutter/services.dart'; // Add this into your main() await SystemChrome.setPreferredOrientations([ // Locks Device orientation to always potrait DeviceOrientation.portraitUp, ]);
Loading Indicator
class SomeWidget extends StatefulWidget { @override _SomeWidgetState createState() => _SomeWidgetState(); } class _SomeWidgetState extends State<SomeWidget> { Future future; @override void initState() { future = Future.delayed(Duration(seconds: 1)); super.initState(); } @override Widget build(BuildContext context) { return FutureBuilder( future: future, builder: (context, snapshot) { return snapshot.connectionState == ConnectionState.done ? Text('Loaded') : CircularProgressIndicator(); }, ); } }
Show Dialog Alert
// ShowDialog Builtin Function showDialog<void>( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: Text('Alert Title'), content: Text('My Alert Msg'), actions: <Widget>[ FlatButton( child: Text('Ask me later'), onPressed: () { print('Ask me later pressed'); Navigator.of(context).pop(); }, ), FlatButton( child: Text('Cancel'), onPressed: () { print('Cancel pressed'); Navigator.of(context).pop(); }, ), FlatButton( child: Text('OK'), onPressed: () { print('OK pressed'); Navigator.of(context).pop(); }, ), ], ); }, );
Form
Import Get from Pub
dependencies: get:
Generate GlobalKey for the form validation
GlobalKey<FormState> key = GlobalKey<FormState>();
Call this function where to show popup
Get.bottomSheet( BottomSheet( onClosing: () => Get.back(), builder: (context) { return Form( key: key, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( icon: Icon(Icons.close), onPressed: () => Get.back(), ), Text( 'Form Title here', style: GoogleFonts.pacifico( textStyle: TextStyle(fontSize: 22.0), ), ), IconButton( icon: Icon(Icons.check), onPressed: () { if (key.currentState.validate()) { // Get.to(); key.currentState.save(); Get.close(0); Get.snackbar( 'Done', 'Data is submitted Successfully!', snackPosition: SnackPosition.BOTTOM); } }, ), ], ), TextFormField( maxLength: 30, keyboardType: TextInputType.name, // inputFormatters: [FilteringTextInputFormatter.digitsOnly], decoration: InputDecoration( prefixIcon: Icon(Icons.person_sharp), helperText: 'i.e Usama Sarwar', labelText: 'Full Name', ), validator: (_val) { if (_val.isEmpty) { return '*Required'; } else { return null; } }, onChanged: (_val) { // Save _val in some variable }, ) ], ), ), ); }, ), isScrollControlled: true, );
Download Flutter Capsule source code on GitHub
Provides the list of the opensource Flutter apps collection with GitHub repository.