Tag: Flutter

  • How to fix flutter camera image picker rotation issue?

    How to fix flutter camera image picker rotation issue?

    Flutter camera image picker has a known issue of returning images with wrong unexpected rotation. The issue has been raised in the GitHub and marked as closed, but still occurs in the latest stable release. The issue can, however, be resolved easily with the help of exif-rotation plugin. This issue is known to be affecting both iOS and Android platforms.

    Why the image is rotated

    When we take an image from the camera, we could be holding the phone in any orientation. Sometimes we take photos in landscape mode, sometimes portait and so on. The camera app takes the photo and adds special metadata entries (EXIF data) to the file so that it can be rotated properly in image viewers.

    Flutter image_picker has a bug where it doesn’t process the image with the given EXIF data which makes the image appear in the wrong rotation. However, we can fix it by considering the EXIF data and rotating the image manually as the metadata suggests.

    How to fix the rotation?

    To fix the unwanted image rotation, we need to rotate the image based on the metadata available. Luckily, a library named flutter_exif_rotation is available. Once the image is taken from the image-picker, give it to the FlutterExifRotation library. The library will rotate it, if needed, based on the available EXIF data.

    Let’s have a look into the sample code.

    Firstly, add the flutter_exif_rotation library to your pubspec.yaml file.

    dependencies:
      ...
      flutter_exif_rotation: ^0.5.1
      ...
    

    Sample code for image pick and rotation fix

    import 'dart:async';
    import 'dart:io';
    
    import 'package:flutter_exif_rotation/flutter_exif_rotation.dart'; //EXIF rotation library
    import 'package:image_picker/image_picker.dart'; //Image picker library
    
    class CameraService {
    
      Future<XFile?> pickImage() async {
        //Take a photo from camera
        final XFile? image = await ImagePicker().pickImage(
          source: ImageSource.camera, maxWidth: 1200, maxHeight: 1200, requestFullMetadata: true
        );
        if (image != null) {
          // Rotate the image to fix the wrong rotation coming from ImagePicker
          File rotatedImage = await FlutterExifRotation.rotateImage(path: image.path);
          return XFile(rotatedImage.path); //Return the file
        }
        return image;
      }
    
    }
    

    In the above code, The function FlutterExifRotation#rotateImage will fix the rotation of the image by considering the EXIF orientation tags. This solution has been proposed in the GitHub and many people supported this as the best way available at the moment.

    If you have liked this article, you might also like other Fltuter tutorials I have written.

  • Encryption and decryption in flutter

    Encryption and decryption in flutter

    This tutorial explores the data encryption and decryption using the dart language for the flutter apps. We come across the requirements of encrypting and decrypting data when we start building real-world applications.

    For supporting encryption, we need to add a library called encrypt. It provides all the functionalities we require for encrypting, encoding encrypted data to base16 or base64, and of course for decryption.

    Add the following line into your pubspec.yaml file under dependencies: section. This will add the ‘encrypt’ library into our project.

    encrypt: ^5.0.1
    

    To use the library in the code, import it as follows.

    import 'package:encrypt/encrypt.dart';
    

    AES Encryption & Decryption

    AES aka Advanced Encryption Standard is a very widely used symmetric block encryption technique. AES can use 128, 192 or 256 length keys.

    How the encryption key bit length is calculated?

    The AES-128 can have a 128-bit key. You can either use the Key.fromSecureRandom(16) function to generate 128-bit keys. Or else, you need to provide a 16 character string as a key.

    For example,

    • “I am 16-char key” contains 16 characters. Each character is 8 bit wide. It can be used as a 128-bit key.
    • “This 32 char key have 256 bits!!” contains 32 characters. Each character is 8 bit wide. So, it will become 256-bit key.

    Example program for AES-CBC encryption and decryption

    Let’s understand the encryption and decryption with an example code. The following program utilizes AES-CBC-PKSC7 algorithm.

    import 'package:encrypt/encrypt.dart';
    
    void main() {
      final plainText = "Fallback! I repeat fallback to sector 12!!";
      final key = "This 32 char key have 256 bits..";
    
      print('Plain text for encryption: $plainText');
    
      //Encrypt
      Encrypted encrypted = encryptWithAES(key, plainText);
      String encryptedBase64 = encrypted.base64;
      print('Encrypted data in base64 encoding: $encryptedBase64');
    
      //Decrypt
      String decryptedText = decryptWithAES(key, encrypted);
      print('Decrypted data: $decryptedText');
    }
    
    ///Accepts encrypted data and decrypt it. Returns plain text
    String decryptWithAES(String key, Encrypted encryptedData) {
      final cipherKey = Key.fromUtf8(key);
      final encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc)); //Using AES CBC encryption
      final initVector = IV.fromUtf8(key.substring(0, 16)); //Here the IV is generated from key. This is for example only. Use some other text or random data as IV for better security.
    
      return encryptService.decrypt(encryptedData, iv: initVector);
    }
    
    ///Encrypts the given plainText using the key. Returns encrypted data
    Encrypted encryptWithAES(String key, String plainText) {
      final cipherKey = Key.fromUtf8(key);
      final encryptService = Encrypter(AES(cipherKey, mode: AESMode.cbc));
      final initVector = IV.fromUtf8(key.substring(0, 16)); //Here the IV is generated from key. This is for example only. Use some other text or random data as IV for better security.
    
      Encrypted encryptedData = encryptService.encrypt(plainText, iv: initVector);
      return encryptedData;
    }
    

    The output of the program is as follows

    Plain text for encryption: Fallback! I repeat fallback to sector 12!!
    Encrypted data in base64 encoding: WI18tczGAOQfiLKGyKyXKcuCZeK9d8K9ONUeVvPEnC8H86l0EBWa76drqdZpmcXO
    Decrypted data: Fallback! I repeat fallback to sector 12!!
    
    Flutter AES Encryption and Decryption Example Output
    Flutter AES Encryption and Decryption Example Output

    What is an initialization vector?

    IV or initVector as denoted in the above code is known as initialization vector. It is an arbitrary data that can be used along with a secret key for more secure data encryption. This is needed because, multiple people can use the same key and create the same encrypted data which can then be compromised. Using IV along with key make sure that the probability of being someone else using IV and KEY is very less. In the above code snippet, the IV is derived from key. It is for example purpose only. Always use random generated IV.

    RSA Encryption and Decryption

    RSA(Rivest Shamir Adleman) is a widely used public-key asymmetric encryption algorithm. You can do encryption and decryption with RSA in flutter with the encrypt library.

    import 'package:encrypt/encrypt.dart';
    import 'package:pointycastle/asymmetric/api.dart';
    
    void main() {
      final publicKey = await readKeyFromFile<RSAPublicKey>('/public.pem'); //Read public key from file
      final privateKey = await readKeyFromFile<RSAPrivateKey>('/private.pem'); //Read private key from file
    
      final plainText = 'Your plain text to be encrypted';
      final encryptService = Encrypter(RSA(publicKey: publicKey, privateKey: privateKey));
    
      //Encrypt
      final encrypted = encryptService.encrypt(plainText);
      final encryptedBase64 = encrypted.base64;
      print('Encrypted data in base64 encoding: $encryptedBase64');
    
      //Decrypt
      final decrypted = encryptService.decrypt(encrypted);
      print('Decrypted data: $decrypted');
    }
    

    You can find more elaborate example here in GitHub.

    More supported algorithms

    The ‘encrypt’ library support some other encryption algorithms like Fernet and Salsa20.

    Conclusion

    In this tutorial, we have explored the encryption and decryption support in dart for flutter apps. We have analyzed an example program for AES algorithm and went through an RSA algorithm example as well. If you liked this article, you might want to have a look into some other flutter articles I have written.

  • Flutter TextField Tutorial

    Flutter TextField Tutorial

    TextField widgets are used for reading text inputs, like username, password, phone number, email address, etc. from the keyboard. They are one of the most commonly used widgets in Flutter, just like Buttons. Flutter TextField follows the Google’s material design principles and is fully compliant with the material design text-field specifications.

    Create a simple TextField

    By default, the TextButton component has only a simple line/divider at the bottom. No other decorations are given. Let’s see how the TextField looks in its bare form.

    Flutter textfield with default style
    Flutter textfield with default style

    The following code generated the above output. In the example code, a no-arg constructor is used to prepare the TextField.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const TextFieldTutorial());
    }
    
    class TextFieldTutorial extends StatelessWidget {
      const TextFieldTutorial({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData(primarySwatch: Colors.teal),
          home: Scaffold(
              appBar: AppBar(title: const Text('TextField Example')),
              body: const TextFieldWidget()),
        );
      }
    }
    
    class TextFieldWidget extends StatelessWidget {
      const TextFieldWidget({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const Center(
            //Create a text field
            child: TextField()
        );
      }
    }
    

    The TextField constructor has many parameters for customization. This widget being one of the most used widgets in all the framework widgets, it indeed has to have as many customizations as the SDK can provide. Click the following code snippet header to view the constructor and all its options;

    const TextField({
     Key? key,
     TextEditingController? controller,
     FocusNode? focusNode,
     InputDecoration? decoration = const InputDecoration(),
     TextInputType? keyboardType,
     TextInputAction? textInputAction,
     TextCapitalization textCapitalization = TextCapitalization.none,
     TextStyle? style,
     StrutStyle? strutStyle,
     TextAlign textAlign = TextAlign.start,
     TextAlignVertical? textAlignVertical,
     TextDirection? textDirection,
     bool readOnly = false,
     ToolbarOptions? toolbarOptions,
     bool? showCursor,
     bool autofocus = false,
     String obscuringCharacter = '•',
     bool obscureText = false,
     bool autocorrect = true,
     SmartDashesType? smartDashesType,
     SmartQuotesType? smartQuotesType,
     bool enableSuggestions = true,
     int? maxLines = 1,
     int? minLines,
     bool expands = false,
     int? maxLength,
     MaxLengthEnforcement? maxLengthEnforcement,
     ValueChanged<String>?onChanged,
     VoidCallback? onEditingComplete,
     ValueChanged<String>?onSubmitted,
     AppPrivateCommandCallback? onAppPrivateCommand,
     List<TextInputFormatter>?inputFormatters,
     bool? enabled,
     double cursorWidth = 2.0,
     double? cursorHeight,
     Radius? cursorRadius,
     Color? cursorColor,
     BoxHeightStyle selectionHeightStyle = ui.BoxHeightStyle.tight,
     BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.tight,
     Brightness? keyboardAppearance,
     EdgeInsets scrollPadding = const EdgeInsets.all(20.0),
     DragStartBehavior dragStartBehavior = DragStartBehavior.start,
     bool? enableInteractiveSelection,
     TextSelectionControls? selectionControls,
     GestureTapCallback? onTap,
     MouseCursor? mouseCursor,
     InputCounterWidgetBuilder? buildCounter,
     ScrollController? scrollController,
     ScrollPhysics? scrollPhysics,
     Iterable<String>?autofillHints = const<String>[],
     Clip clipBehavior = Clip.hardEdge,
     String? restorationId,
     bool scribbleEnabled = true,
     bool enableIMEPersonalizedLearning = true 
    })
    

    Customize the TextField

    Let’s learn how to customize the TextField widget with an email input example. We need to make the widget look like the material design TextField with nice rounded borders with label. Let’s also add an email icon.

    We will do the following customizations:

    • Set a rounded border with border label
    • Set a hint text
    • Set an email icon at the start position of the TextField
    • Set font size to 18dp
    • Set input type to email so that the virtual keyboard will adjust accordingly (will show @ button)
    TextField with Icon in Flutter
    Customized TextField in flutter with icon, label, hint and email keyboard-type.
    class TextFieldWidget extends StatelessWidget {
      const TextFieldWidget({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const Center(
          child: TextField(
            //Set text style
            style: TextStyle(
              fontSize: 18
            ),
            keyboardType: TextInputType.emailAddress, //Set keyboard type for email address. This will show @ button on the primary section of the keyboard.
            //Set decoration
            decoration: InputDecoration(
                border: OutlineInputBorder(), //Create rounded outlined border
                labelText: "Email", //Set the label text that will be shown over the border
                prefixIcon: Icon(Icons.email), // Set email icon at the start of the TextField
                hintText: "Enter your email ID"), // Set the hint text that will be shown when TextField is empty
          ),
        );
      }
    }
    

    Retrieve typed text input from TextField

    Flutter has multiples ways to get and process text from the TextField widget. The best approach is to use a TextController class to handle all the events coming out of the TextField properly. The simplest approach is to use an onChange() callback.

    Also, it is possible to track every change happening on the text field (For example, while entering hello, get callback after each letter h, e, l, l, and o separately). On the other hand, if you are interested only when the text field input is finished and user wants to submit the data, there is a callback method for that as well.

    Let’s see all these options in detail.

    Tracking every text change in the TextField

    First, let’s see how we can track every change happening on the TextField. There are two ways to do this.

    1. Using onChange() callback
    2. TextEditingController

    Using onChange() callback – The easy way

    onChange() callback can be added by providing it to the TextField constructor. We can provide a function to the onChanged property to register an onChange callback. This will print “Entered value: …..” as soon as we start typing contents to the TextField.

    class TextFieldWidget extends StatelessWidget {
      const TextFieldWidget({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Center(
          child: TextField(
            onChanged: (value) {
              print('Entered value: $value');
            },
            style: const TextStyle(fontSize: 18),
            keyboardType: TextInputType.emailAddress,
            decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "Email", prefixIcon: Icon(Icons.email), hintText: "Enter your email ID"),
          ),
        );
      }
    }
    
    Flutter TextField onChange callback
    Flutter TextField onChange callback firing print output for each keystroke

    Using TextEditingController – The best way

    Using TextEditingController is recommended since it is easier to use as the text-value from the text field needs to be used on other widgets. For using TextEditingController, we have to do the following steps.

    1. Create a TextEditingController
    2. Create a function that executes whenever the text is changed
    3. Link the function to the TextEditingController inside initState() function. This is for creating the link between controller and function
    4. Dispose the TextEditingController inside dispose() for resource cleanup
    5. Link the controller to the TextField via the controller attribute
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const TextFieldTutorial());
    }
    
    class TextFieldTutorial extends StatefulWidget {
      const TextFieldTutorial({Key? key}) : super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return TextFieldWidget();
      }
    }
    
    class TextFieldWidget extends State<TextFieldTutorial> {
    
      //Create new TextEditingController
      final emailTextFieldController = TextEditingController();
    
      @override
      void initState() {
        super.initState();
        //Link controller to the function to be executed on change
        emailTextFieldController.addListener(printTextFieldValue);
      }
    
      @override
      void dispose() {
        //Dispose the controller when the widget is disposed
        emailTextFieldController.dispose();
        super.dispose();
      }
    
      //Function that executes when the text is changed
      void printTextFieldValue() {
        print('Second text field: ${emailTextFieldController.text}');
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(primarySwatch: Colors.blue),
          home: Scaffold(
            appBar: AppBar(title: const Text('TextField Example')),
            body: Padding(
              padding: const EdgeInsets.all(50),
              child: TextField(
                controller: emailTextFieldController, //Link controller to TextField
                style: const TextStyle(fontSize: 18),
                keyboardType: TextInputType.emailAddress,
                decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "Email", prefixIcon: Icon(Icons.email), hintText: "Enter your email ID"),
              ),
            ),
          ),
        );
      }
    }
    

    Tracking text submission event with onSubmitted callback

    So far, we have seen how to track every text change inside the TextField. Most of the time, we might not be interested in the individual text changes, but on the final text the user submits. Flutter provides a callback for the submission event as well. This callback can be registered through the onSubmitted parameter.

    The onSubmitted callback will be fired only when you press the Submit button on the keyboard. In Android and iOS, it is the ‘check’ or ‘tick’ button on the keyboard. On the desktop platform, it is the ENTER key. In the following gif image, you can see that the onSubmitted function is fired only after the check button was pressed.

    class TextFieldWidget extends StatelessWidget {
      const TextFieldWidget({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Center(
          child: TextField(
            onSubmitted: (submittedValue) {
              print('Submitted value: $submittedValue');
            },
            style: const TextStyle(fontSize: 18),
            keyboardType: TextInputType.emailAddress,
            decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "Email", prefixIcon: Icon(Icons.email), hintText: "Enter your email ID"),
          ),
        );
      }
    }
    
    Flutter TextField onSubmitted callback
    Flutter TextField onSubmitted callback example

    Example program: Change label value automatically when TextField text is changed

    Let’s apply what we have learned so far in this chapter into a full example application. The requirement is as follows.

    Requirement – There are two widgets in the screen, one “Text” and one “TextField” widget. Automatically update label/text component value when the input on the TextField is changed.

    The solution for the problem is given below.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const TextFieldTutorial());
    }
    
    class TextFieldTutorial extends StatefulWidget {
      const TextFieldTutorial({Key? key}) : super(key: key);
    
      @override
      State<StatefulWidget> createState() {
        return TextFieldWidget();
      }
    }
    
    class TextFieldWidget extends State<TextFieldTutorial> {
      String state = "";
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(primarySwatch: Colors.blue),
          home: Scaffold(
            appBar: AppBar(title: const Text('TextField Example')),
            body: Padding(
              padding: const EdgeInsets.all(50),
              child: Column(children: [
                Text('Entered email address is: $state'), //Set the label text using the state variable
                const SizedBox(height: 20),
                TextField(
                  onChanged: (value) {
                    setState(() => state = value); //Update state as soon as the TextField text is changed
                  },
                  style: const TextStyle(fontSize: 18),
                  keyboardType: TextInputType.emailAddress,
                  decoration: const InputDecoration(border: OutlineInputBorder(), labelText: "Email", prefixIcon: Icon(Icons.email), hintText: "Enter your email ID"),
                ),
              ]),
            ),
          ),
        );
      }
    }
    

    The output of the above code snippet is as follows.

    Flutter TextField and Label Binding
    Flutter TextField and Text Value Binding

    Conclusion

    In this tutorial, we have learned how to use flutter TextField. We have gone through the customization, callbacks like onChange, onSubmit and text field controller options. If this tutorial was useful, you might be interested in the other Flutter tutorials I have written.

  • Flutter OutlinedButton Tutorial (2022)

    Flutter OutlinedButton Tutorial (2022)

    An OutlinedButton is a button with text child and a border outline. It is also a form of TextButton with an outline. They are used in the places where the button needs medium importance. Unlike the other two button types (TextButton and ElevatedButton), these buttons have the outline style set by default.

    OutlinedButton Usage

    There are two constructors available for the OutlinedButton, one with option to specify icon and one without icon. First, let’s try the simple outlined button that does not have any icon.

    There are two mandatory fields in the constructor, onPressed and child.

    const OutlinedButton({
        Key? key,
        required VoidCallback? onPressed,
        VoidCallback? onLongPress,
        ValueChanged<bool>? onHover,
        ValueChanged<bool>? onFocusChange,
        ButtonStyle? style,
        FocusNode? focusNode,
        bool autofocus = false,
        Clip clipBehavior = Clip.none,
        required Widget child,
    });
    

    Now, let’s see how we can make use of the OutlinedButton in a sample application. In the following example, when the button is pressed, a snackbar message will be shown.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const OutlinedButtonExample());
    }
    
    class OutlinedButtonExample extends StatelessWidget {
      const OutlinedButtonExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
              appBar: AppBar(title: const Text('OutlinedButton Example')),
              body: const OutlinedButtonWidget()),
        );
      }
    }
    
    class OutlinedButtonWidget extends StatelessWidget {
      const OutlinedButtonWidget({Key? key}) : super(key: key);
    
      //Button click handler: Show snackbar
      handleButtonClick(BuildContext context) {
        const snackBar = SnackBar(
          content: Text("Outlined Button Clicked!"),
        );
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      }
    
      @override
      Widget build(BuildContext context) {
        return Center(
          //Create Text Button
          child: OutlinedButton(
              //Handle button press event
              onPressed: () {
                handleButtonClick(context);
              },
              //Contents of the button
              child: const Text("Click Outlined Button!")),
        );
      }
    }
    

    This code generates the following output.
    Flutter OutlinedButton Example

    Customize style and add an Icon

    Now, let’s see how we can customize the OutlinedButton with the styling options available and add an icon into the button.

    There’s a factory constructor available for making the button with an Icon. As you can see from the constructor signature below, 3 fields are mandatory. onPressed, icon and the label.

    factory OutlinedButton.icon({
      Key? key,
      required VoidCallback? onPressed,
      VoidCallback? onLongPress,
      ButtonStyle? style,
      FocusNode? focusNode,
      bool? autofocus,
      Clip? clipBehavior,
      required Widget icon,
      required Widget label,
    })
    

    For the button style customization, we will do the following.

    • Set font size to 20dp
    • Set font size to 20dp
    • Add 20px padding on all sides
    • Set the border color GREEN
    • Set the border width to 2px
    • Set the text color GREEN
    OutlinedButton With Icon
    OutlinedButton With Icon and customized style

    Now, let’s see we can do it with an example code.

    class OutlinedButtonWidget extends StatelessWidget {
      const OutlinedButtonWidget({Key? key}) : super(key: key);
    
      handleButtonClick(BuildContext context) {
        ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Outlined Button Clicked!")));
      }
    
      @override
      Widget build(BuildContext context) {
        return Center(
          //Create Elevated Button
          child: OutlinedButton.icon(
              //Handle button press event
              onPressed: () {
                handleButtonClick(context);
              },
              //Contents of the button
              style: ElevatedButton.styleFrom(
                //Style the text
                textStyle: const TextStyle(
                  fontSize: 20, //Set font size
                ),
                //Style the border
                side: const BorderSide(
                  color: Colors.green, //Set border color
                  width: 2, //Set border width
                ),
                onPrimary: Colors.green, //Set the foreground (text + icon) color
                padding: const EdgeInsets.all(20.0), //Set the padding on all sides to 20px
              ),
              icon: const Icon(Icons.download), //Button icon
              label: const Text("Click OutlinedButton!")), //Button label
        );
      }
    }
    

    Customizing flutter buttons further

    You can customize even more to the minute details of the buttons, thanks to the flutter SDK. We have discussed this in detail in the ElevatedButton article. If you are interested, please refer the article.

    Conclusion

    In this tutorial, we have learned how to make use of the Flutter OutlinedButton widget in flutter. This button is useful for non-primary actions in the GUI because it doesn’t attract too much attention for the user. We have seen how to customize it with icons and custom style. If you liked this article, you might be interested in the other Flutter tutorials I have written.

  • How to generate UUID in dart / flutter

    How to generate UUID in dart / flutter

    Very often, we come across the need to have UUID. UUIDs are perfect for giving unique ID to objects and resources. In this tutorial, we will see how to create UUID in dart for a flutter app.

    Generating the UUID

    Step 1: Add the uuid library to your project

    To create UUIDs, we need to add the uuid library into the project. It can be added by inserting the following entry into your project’s pubsec.yaml file.

      uuid: 3.0.6
    

    Step 2: Import “uuid/uuid.dart” and use it

    Now, let’s use the added library to create UUID. First, import the library and then use it. Simply create an object of the Uuid() class and then use the provided v1(), v2(), v3(), v4(), or v5() function based on the UUID version you need. All the standard UUID versions are supported in this library.

    import 'package:uuid/uuid.dart';
    ...
    createUuid() {
      const uuid = Uuid();
      //Create UUID version-4
      return uuid.v4();
    }
    
    import 'package:uuid/uuid.dart';
    
    createV5Uuid() {
      return Uuid().v5(Uuid.NAMESPACE_URL, 'www.genuinecoder.com');
    }
    

    If you are looking for more customized UUIDs with more control over the random data, have look into the library example section.

    Create Unique ID without additional libraries

    Now, let’s say you don’t need UUID exactly, but want unique auto-generated IDs. Then you can proceed with the UniqueKey class.

    UniqueKey() will return an alphanumeric string (usually 5 char length).

    createUUID() {
      return UniqueKey();
    }
    

    Conclusion

    In this tutorial, we have seen how to generate UUID with flutter. The UUID library supports all the standard variations and is straightforward to use. If you have liked this article, have a look into the other flutter tutorials I have written.

  • Flutter ElevatedButton Tutorial (2022)

    Flutter ElevatedButton Tutorial (2022)

    In this tutorial, we will explore the ElevatedButton widget in Flutter. ElevatedButtons are, as the name suggests, buttons with a depth or elevation. They will stand on top of the container with a shadow. So they have a different appearance compared to the flat button TextButton.

    ElevatedButton without Icon

    There are two constructors available for the ElevatedButton, one with icon and one without icon. Let’s first see how to use the one without icon.

    There are two mandatory fields in the constructor, onPressed and child.

    const ElevatedButton({
        Key? key,
        required VoidCallback? onPressed,
        VoidCallback? onLongPress,
        ValueChanged<bool>? onHover,
        ValueChanged<bool>? onFocusChange,
        ButtonStyle? style,
        FocusNode? focusNode,
        bool autofocus = false,
        Clip clipBehavior = Clip.none,
        required Widget? child
    })
    

    Let’s see how we can create this button with an example code.

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const ElevatedButtonExample());
    }
    
    class ElevatedButtonExample extends StatelessWidget {
      const ElevatedButtonExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
              appBar: AppBar(title: const Text('ElevatedButton Example')),
              body: const ElevatedButtonWidget()),
        );
      }
    }
    
    class ElevatedButtonWidget extends StatelessWidget {
      const ElevatedButtonWidget({Key? key}) : super(key: key);
    
      //Button click handler: Show snackbar
      handleButtonClick(BuildContext context) {
        const snackBar = SnackBar(
          content: Text("ElevatedButton Clicked!"),
        );
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      }
    
      @override
      Widget build(BuildContext context) {
        return Center(
          //Create Elevated Button
          child: ElevatedButton(
              //Handle button press event
              onPressed: () {
                handleButtonClick(context);
              },
              //Contents of the button
              child: const Text("Click ElevatedButton!")),
        );
      }
    }
    

    The above code generates the following output. Note that the color of the button is taken from the default theme. We will see how to customize the colors and fonts in the next section.

    Simple Flutter ElevatedButton
    Simple Flutter ElevatedButton

    Customize button style and add an icon

    Now, let’s see how to customize the button and add an icon to it. The ElevatedButton class has a separate constructor for creating the button with an icon. We will make use of that.

    For styling the button, ElevatedButton.styleFrom() to update the values from the default theme.

    factory ElevatedButton.icon({
        Key? key,
        required VoidCallback? onPressed,
        VoidCallback? onLongPress,
        ValueChanged<bool>? onHover,
        ValueChanged<bool>? onFocusChange,
        ButtonStyle? style,
        FocusNode? focusNode,
        bool? autofocus,
        Clip? clipBehavior,
        required Widget icon,
        required Widget label,
    })
    

    For the button style customization, we will do the following.

    • Add a download icon
    • Change the font size to 22dp
    • Add 20px padding on all sides
    • Set the foreground color to RED
    • Set the background color to YELLOW

    Now, let’s see we can do it with an example code.

    @override
    Widget build(BuildContext context) {
        return Center(
            //Create Elevated Button
            child: ElevatedButton.icon(
                //Handle button press event
                onPressed: () {
                  handleButtonClick(context);
                },
                //Contents of the button
                style: ElevatedButton.styleFrom(
                  //Change font size
                  textStyle: const TextStyle(
                      fontSize: 22,
                  ),
                  //Set the background color
                  primary: Colors.yellow,
                  //Set the foreground (text + icon) color
                  onPrimary: Colors.red,
                  //Set the padding on all sides to 30px
                  padding: const EdgeInsets.all(30.0),
                ),
                icon: const Icon(Icons.send_rounded), //Button icon
                label: const Text("Click Text Button!")), //Button label
        );
    }
    

    This will generate the following output. As you can see below, the

    ElevatedButton with icon and theme customization
    ElevatedButton with icon and theme customization

    More button style customization

    Let’s go through all the style customization flutter provides for the ElevatedButton. All the following mentioned customizations can be used within ElevatedButton.styleFrom(), Just like we did in the above example for padding, color etc.

    Set the disabled state color (applies for button label and icon)
    onSurface: Colors.colorOfYourChoice
    
    Set the shadow/elevation color
    shadowColor: Colors.colorOfYourChoice
    
    Set the elevation.

    Higher the elevation, more the shadow spread.

    elevation: 6.0
    
    Specify minimum size of the button
    //First parameter is width, second is height.
    minimumSize: Size(20, 40)
    
    Set the button border
    //Setting solid 1px red color border
    side: BorderSide(color: Colors.red, width: 1.0, style: BorderStyle.solid),
    //Setting sold 1px red color border
    
    Set button shape
    //Setting button shape to circle with radius of 35.
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(35.0)), 
    
    Mouse cursor when button is enabled
    //Set mouse cursor to click (hand cursor)
    enabledMouseCursor: SystemMouseCursors.click,
    //Set mouse cursor to text (I cursor)
    
    Button with custom cursor, rounded corners, border, etc.
    Button with custom cursor, rounded corners, border, etc.
    Mouse cursor when button is disabled
    //Hide mouse cursor when hovered over disabled ElevatedButton
    disabledMouseCursor: SystemMouseCursors.none,
    
    Set visual density
    visualDensity: VisualDensity(horizontal: 0.0, vertical: 0.0)
    
    Set tap target size
    tapTargetSize: MaterialTapTargetSize.padded
    
    Set button’s default animation duration for shape change and elevation change
    //Setting the animation duration to 100ms
    animationDuration: Duration(milliseconds: 100)
    
    Enable/disable button click feedback

    Enable or disable vibration (haptic) and sound (acoustic) feedbacks.

    enableFeedback: true
    
    Alighnment of button’s text
    alignment: Alignment.bottomCenter
    
    Background color of the button
    primary: Colors.yourPrefferedBackground
    
    Foreground color of the button icon + text
    onPrimary: Colors.yourFavouriteForegroundColor
    
    Change font properties
    //Set font size and font weight
    textStyle: const TextStyle(
           fontSize: 20,
           fontWeight: FontWeight.bold,
    ),
    
    Set button padding
    //Set the padding on all sides to 20px
    padding: const EdgeInsets.all(20.0),
    

    Conclusion

    In this chapter, we have learned how to make use of the ElevatedButton widget in Flutter. We have seen how to create one with icon, without icon and went through all the style customizations we can do for the button. If you liked this article, you might be interested in the other Flutter tutorials I have written.

  • Flutter TextButton Widget – Usage and Examples

    Flutter TextButton Widget – Usage and Examples

    In this tutorial, we will explore the Button widgets available in the Flutter. Compared to the previous version Flutter2, Flutter3 has updated the button widget. We will see how to use the TextButton widget and customize it. If you want to learn how to create your first flutter project, head over to this tutorial on making your first flutter project.

    TextButtons, as the name suggests, are widgets with simple text that can be interacted with a click. It uses the theme “TextButtonTheme”. These buttons are useful for action in dialogs, snackbars and cards. The material design 3 specifications for the TextButton can be found in here.

    TextButton without Icon

    Constructor of the TextButton given below. The onPressed and child properties are mandatory.

    TextButton({
        Key? key,
        required VoidCallback? onPressed, //onPressed is mandatory
        VoidCallback? onLongPress,
        ValueChanged<bool>? onHover,
        ValueChanged<bool>? onFocusChange,
        ButtonStyle? style,
        FocusNode? focusNode,
        bool autofocus = false,
        Clip clipBehavior = Clip.none,
        required Widget child,            //child is mandatory
    })
    

    Let’s see how we can use the button on a sample application.

    Flutter TextButton without icon
    Flutter TextButton with Snackbar message on press action
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const TextButtonExample());
    }
    
    class TextButtonExample extends StatelessWidget {
      const TextButtonExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
              appBar: AppBar(title: const Text('TextButton Example')),
              body: const TextButtonWidget()),
        );
      }
    }
    
    class TextButtonWidget extends StatelessWidget {
      const TextButtonWidget({Key? key}) : super(key: key);
    
      //Button click handler: Show snackbar
      handleButtonClick(BuildContext context) {
        const snackBar = SnackBar(
          content: Text("Text Button Clicked!"),
        );
        ScaffoldMessenger.of(context).showSnackBar(snackBar);
      }
    
      @override
      Widget build(BuildContext context) {
        return Center(
          //Create Text Button
          child: TextButton(
            //Handle button press event
            onPressed: () {
              handleButtonClick(context);
            },
            //Contents of the button
            child: const Text("Click Text Button!")
          ),
        );
      }
    }
    

    Customize the TextButton

    TextButton uses the theme TextButtonTheme. Let’s see how we apply the following style updates for the Button.

    1. Change the font size to 20: Use textStyle
    2. Make the button font bold: Use textStyle
    3. Change the text color to RED: Use primary
    4. Add padding of 20px on all sides: Use padding
    @override
    Widget build(BuildContext context) {
      return Center(
        //Create Text Button
        child: TextButton(
          //Handle button press event
            onPressed: () {
              handleButtonClick(context);
            },
            style: TextButton.styleFrom(
                //Change font size and weight
                textStyle: const TextStyle(
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
                //Set the foreground color
                primary: Colors.red,
                //Set the padding on all sides to 20px
                padding: const EdgeInsets.all(20.0),
            ),
            //Contents of the button
            child: const Text("Click Text Button!")),
      );
    }
    
    Customized Flutter 3 TextButton
    Customized Flutter TextButton

    TextButton with Icon

    Now, let’s see how we can create the TextButton with an icon. There is a special factory constructor available for creating TextButton with an Icon. Let’s have a look into the factory constructor.

    factory TextButton.icon({
        Key? key,
        required VoidCallback? onPressed,  //onPressed is mandatory
        VoidCallback? onLongPress,
        ValueChanged<bool>? onHover,
        ValueChanged<bool>? onFocusChange,
        ButtonStyle? style,
        FocusNode? focusNode,
        bool? autofocus,
        Clip? clipBehavior,
        required Widget icon,             //Icon is mandatory
        required Widget label,            //Label is mandatory
    })
    

    As it can be seen from the above constructor, we need to provide an icon, label and onPressed values.

    Let’s see how we can do this with an example code.

    @override
    Widget build(BuildContext context) {
      return Center(
        //Create Text Button
        child: TextButton.icon(
            onPressed: () {
              handleButtonClick(context);
            },
            style: TextButton.styleFrom(
              //Change font size and weight
              textStyle: const TextStyle(
                fontSize: 20,
                fontWeight: FontWeight.bold,
              ),
              //Set the foreground color
              primary: Colors.deepOrange,
              //Set the padding on all sides to 20px
              padding: const EdgeInsets.all(20.0),
            ),
            //Set the icon
            icon: const Icon(Icons.send_rounded),
            //Set the label
            label: const Text("Click Text Button!")),
      );
    }
    

    It generates the following output. As you can see, the icon is added to the button, the label is set and the customized styling is applying.

    TextButton With Icon
    Flutter TextButton with an icon

    Conclusion

    In this tutorial, we have learned how to use the TextButtons in flutter. We have seen how to use it, customize it, and add icons to it. If you liked this article, you might want to check out my other Flutter tutorials.

  • Create your first flutter desktop application – Flutter tutorial

    Create your first flutter desktop application – Flutter tutorial

    Flutter is the new developer-friendly cross-platform open-source framework developed by Google. The flutter community is growing and as of 2022, with flutter 3, it is stable for Android, iOS, Web and Desktop platforms! Flutter 3 added stable support for Linux desktop and macOS platform.

    In this tutorial for beginners, we will learn how to create a simple flutter application and build it as a native desktop application for Linux.

    Setting up the flutter development environment

    Based on your platform, the steps for installing the flutter and configuring is a bit different. In this tutorial, we will cover the setting up of flutter SDK for Linux Ubuntu platform.

    Install and configure flutter for Ubuntu/Mint

    • Step 1: Install the flutter SDK using snap

            sudo snap install flutter --classic
          
    • Step 2: Install additional dependencies for flutter-sdk’s development

            sudo apt-get install clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev
          
    • Step 3 [OPTIONAL]: Link Android Studio to the flutter by providing Android Studio installed path

            flutter config --android-studio-dir /your/path/to/android-studio/
          
    • Step 4 [OPTIONAL]: Link Android SDK to the flutter by providing Android SDK installed path

            flutter config --android-sdk /usr/local/bin/Programs/android-sdk/
          
    • Step 5 [OPTIONAL]: Accept Android SDK licenses by running the following command

            flutter doctor --android-licenses
          
    • Step 6: Run the flutter doctor command again. Now all dependencies should be ticked!

            flutter doctor --android-licenses
          

    Flutter Ubuntu Install

    Enable flutter desktop development support

    First things first, let’s confirm that flutter SDK desktop support is enabled. To do this, run the command “flutter devices” and make sure that your desktop platform is indeed listed as shown in the below screenshot. Note that, based on your platform, it could be Linux (desktop), Windows (desktop) or macOS (desktop).
    Flutter devices command

    #Command format
    flutter config --enable-<platform>-desktop
    #Enable Linux desktop support for flutter
    flutter config --enable-windows-desktop
    #Enable Windows desktop support for flutter
    flutter config --enable-linux-desktop
    #Enable macOS desktop support for flutter
    flutter config --enable-macOS-desktop
    

    Create a new flutter desktop project

    Now, let’s create our flutter project. Flutter project can be created with “flutter create” command. Let’s create a new flutter project named “genuine_flutter_app” with the following command. You can use your project’s name.

    flutter create genuine_flutter_app
    

    Now, you will see the following output mentioning that the flutter app is indeed created.

    Creating project genuine_flutter_app...
    Running "flutter pub get" in genuine_flutter_app...              1,968ms
    Wrote 127 files.
    
    All done!
    To run your application, type:
    
      $ cd genuine_flutter_app
      $ flutter run
    
    Your application code is in genuine_flutter_app/lib/main.dart.
    

    The flutter SDK has just created a new folder with default project template and added all the required files for us. We can run the project right away and see if all is good so far.

    Run the flutter app on desktop

    Since the “flutter create” command created the project with template code, we can run it and test it right away. So, let’s run the project with flutter run command. Since I am using Linux, I will be using “-d linux”. If you are using Windows or Mac, make sure to use your platform’s name there.

    #cd into the project directory
    cd genuine_flutter_app
    #Run the project
    flutter run -d linux
    

    and…here we go! You will now see the application window opened. This is the default template project.

    Flutter Linux Desktop Application Running
    Flutter Linux Desktop Application Running

    Customize the default project

    Let’s customize the default project and see how we can program in dart. To achieve this, let’s open the project on our IDE. I am using VSCode. You can choose your own editor.

    Open the file lib/main.dart. This is the source file that is generating the sample demo project. Let’s then customize the project.

    Flutter main.dart
    Flutter main.dart file inside lib directory

    Q1. How to set title of the flutter AppBar?

    Currently, the AppBar title is ‘Flutter Demo Home Page’ that is passed on to the MyHomePage widget. So, let’s change it into ‘My First Flutter Desktop App!’ by changing it in the MyApp widget.

    Q2. How to change the AppBar color?

    The AppBar color can be changed from the theme attribute. Set the primarySwatch as your preferred color and that will update the AppBar color.

    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
    
          //Set the app color there
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          
          // Set the title here
          home: const MyHomePage(title: 'My First Flutter Desktop App!'),
        );
      }
    

    Q3. How to change the app body color?

    To set the background color for the body section, you need to set the background for the scaffold.

    ....
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        //This is where the AppBar title is set
        appBar: AppBar(
          title: Text(widget.title),
        ),
        //Set your preferred background color
        backgroundColor: Colors.grey,
    ....
    

    Build and release executable file from flutter project

    Now that we have a working flutter application, let’s see how we can build an executable file for our project. Thanks to flutter, this is also an easy step. You can execute the “flutter build” command to start the building. If you are using Windows or Mac, make sure to use your platform instead of Linux.

    #Generates Linux runnable image (application/x-executable)
    flutter build linux
    #Generates Windows runnable .exe file
    flutter build windows
    #Generates macOS runnable .app file
    flutter build macos
    

    This will build an executable file for the project. The executable can then be found at the following path. [your_platform] can be Linux, windows and macOS.

    build/[your_platform]/x64/release/bundle
    
    Flutter project released as Linux desktop executable
    Flutter project released as Linux desktop executable

    Conclusion

    In this tutorial, we have learned how to create a Flutter desktop application and build a release executable file from the project. We will be posting more flutter related tutorials in the future. If you liked this tutorial, you might also be interested in checking out the following articles.