Flutter Released 3.19 Version: What’s New? All You Need to Know

After three months, the Flutter team moved from version “3.16” to the “3.19” stable release, introducing many improvements and new features. In this blogpost we will try to learn and understand the latest things from visual and code examples. So, before it gets too late let’s dive in.

According to Kevin Chisholm, Flutter 3.19 has a lot to offer. It includes a new Dart SDK for Gemini and a widget for precise animation control. It also boosts rendering with Impeller updates. There are new tools for deep links and support for Windows Arm64. Plus, there’s much more!

Watch the video or continue reading the blogpost.

Watch the video or continue reading the blogpost.

AI integration into Dart SDK

The “Google AI Dart SDK” is currently in beta. It lets you add generative AI features to your Dart or Flutter app. This is powered by Gemini, Google’s newest AI model family. Use the google_generative_ai package from pub_dev to add ChatBot functionality to your Flutter app.

google generative ai in dart sdk

The process is straightforward. Using that package, take a simple string prompt and feed it to the generateContent() method. In your Flutter app, you can pull this prompt from a text field. Once submitted, call the generateContent() method and show the AI-generated content as a response. This helps you build your own Text Generating ChatBot.

To see this Flutter ChatBot in action using the google_generative_ai package, copy the code example and paste it into DartPad.

// Import necessary packages
import 'package:flutter/material.dart';
import 'package:google_generative_ai/google_generative_ai.dart';

// Replace with your actual API key
const apiKey = 'YOUR_API_KEY';

// Main app widget
class MyChatApp extends StatefulWidget {
  @override
  _MyChatAppState createState() => _MyChatAppState();
}

class _MyChatAppState extends State<MyChatApp> {
  final TextEditingController textController = TextEditingController();

  List<String> messages = []; // Stores chat history

  bool isGenerating = false;

  void sendMessage(String text) async {
    setState(() => isGenerating = true);
    // Create GenerativeModel instance
    final model = GenerativeModel(model: 'gemini-pro', apiKey: apiKey);

    // Prepare request content
    final content = [Content.text(text)];

    // Generate response
    final response = await model.generateContent(content);

    print("response $response");

    print("text ${response.text}");

    // Add messages to chat history
    setState(() {
      messages.add(response.text!);
      isGenerating = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Chatbot')),
        body: Column(
          children: [
            // Chat history display
            Expanded(
              child: ListView.builder(
                itemCount: messages.length,
                itemBuilder: (context, index) {
                  return Text(messages[index]);
                },
              ),
            ),
            isGenerating == true
                ? Center(child: CircularProgressIndicator())
                : Container(),
            // User input field
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: textController,
                    onSubmitted: (text) => sendMessage(text),
                  ),
                ),
                IconButton(
                  icon: Icon(Icons.send),
                  onPressed: () {
                    sendMessage(textController.text);

                    setState(() {
                      messages.add(textController.text);
                    });

                    textController.clear();
                  }, // Get text from field
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

Framework improvements & features

1. Scrolling improvements

Previously, dragging with two fingers would actually double the scroll speed compared to using a single finger. This behavior didn’t align with native platform expectations, potentially causing confusion.

Flutter 3.19 steps in to fix this by making scrolling agnostic to the number of fingers used by configuring default ScrollBehavior with MultiTouchDragStrategy.latestPointer. This means you’ll get the same smooth, predictable scrolling speed regardless of whether you’re using one, two, or even more fingers.

But fear not, customization is still king in Flutter! If you preferred the old behavior, you can easily opt back in by configuring the ScrollBehavior using the MultiTouchDragStrategy.sumAllPointers option. For more info see migration guide.

Other improvements on scrolling includes:

  • SingleChildScrollView and ReorderableList: Numerous bug fixes address reported crashes and unexpected behavior, ensuring these widgets scroll smoothly and reliably.
  • Two-Dimensional Scrolling: An issue where dragging or tapping during ongoing scrolling would lead to unexpected behavior has been resolved, resulting in a more intuitive and responsive experience.

2. Flutter AnimationStyle widget

This powerful tool, championed by community member TahaTesser, empowers you to override the default animation behavior in various widgets like MaterialAppExpansionTile, and PopupMenuButton.

Here is an example where popup menu curve and transition duration is overridden:

popUpAnimationStyle: AnimationStyle(
  curve: Easing.emphasizedAccelerate,
  duration: Durations.medium4,
),

Set AnimationStyle.noAnimation to disable animation.

return MaterialApp(
      themeAnimationStyle: AnimationStyle.noAnimation,

Checkout this pull request for more info on AnimationStyle widget.

SegmentedButton.styleFrom static method

The Flutter framework introduces a new update to the SegmentedButton widget, a feature that underscores the framework’s commitment to consistency and ease of use across its UI component library. This update, contributed by Flutter community member @AcarFurkan, enriches the SegmentedButton with a new method: SegmentedButton.styleFrom. This addition harmonizes the SegmentedButton with other button types within Flutter, offering developers a familiar and streamlined way to customize button styles.

Also read:

Below is the example of SegmentedButton.styleFrom static method:

SegmentedButton styleform code example

Switch.adaptive constructor

In the latest Flutter 3.19 release, an intriguing update has been introduced to enhance cross-platform UI consistency and native aesthetics: the Adaptive Switch. This update is particularly noteworthy for developers aiming to deliver a seamless user experience across iOS, macOS and other platforms without leaning heavily on the Cupertino library for Apple-like UI elements. The Adaptive Switch is a Flutter widget designed to automatically adjust its appearance to match the native look and feel of the platform it runs on.

Below is the example of Switch.adaptive constructor in flutter:

Switch.adaptive(
  value: _isSwitched,
  onChanged: (bool newValue) {
    setState(() {
      _isSwitched = newValue;
    });
  },
)

SemanticsProperties accessibility identifier

Semantics refers to the meaning or interpretation of something. In UI development, semantics pertains to conveying the meaning and purpose of UI elements to users and assistive technologies.

The new accessibility identifier added to SemanticsProperties is a game-changer for enhancing the accessibility of Flutter applications. It provides a unique identifier for each semantic node in the native accessibility hierarchy, bridging a crucial gap in accessibility features offered by Flutter.

On Android, the accessibility identifier is manifested as resource-id in the accessibility hierarchy, while on iOS, it sets the UIAccessibilityElement.accessibilityIdentifier. This deep integration with native platform accessibility features ensures that Flutter apps can leverage the existing screen readers and accessibility tools effectively, providing a seamless experience for users with disabilities.

Implementing accessibility identifier

Semantics(
  child: YourWidget(),
  properties: SemanticsProperties(
    accessibilityIdentifier: 'your_unique_identifier_here',
  ),
)

In this snippet, YourWidget is wrapped in a Semantics widget, where you specify the accessibilityIdentifier within the SemanticsProperties. This identifier should be unique to ensure that accessibility tools and testing frameworks can precisely target the semantic node.

MaterialStatesController enhancing access to text widget state

There’s a new feature that introduces a statesController property to TextField and TextFormField for handling MaterialState changes through a MaterialStatesController, it represents a significant advancement in how developers can interact with the state of text fields. This feature would allow for more dynamic responsiveness in UI components based on their state (e.g., focused, hovered, pressed).

Here’s an example of MaterialStatesController.

In order to see the following MaterialStatesController code example in action, copy and paste it directly to the DartPad.

Also read:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: CustomTextField(),
        ),
      ),
    );
  }
}

class CustomTextField extends StatefulWidget {
  @override
  _CustomTextFieldState createState() => _CustomTextFieldState();
}

class _CustomTextFieldState extends State<CustomTextField> {
  late final MaterialStatesController _statesController;
  final TextEditingController _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    _statesController = MaterialStatesController();

    // Hypothetical listener setup to respond to state changes
    _statesController.addListener(() {
      Set<MaterialState> states = _statesController.value;
      if (states.contains(MaterialState.focused)) {
        // Handle focused state
        print("TextField is focused");
      } else if (states.contains(MaterialState.hovered)) {
        // Handle focused state
        print("TextField is hovered");
      } else {
        // Handle unfocused state
        print("TextField is not focused");
      }
    });
  }

  @override
  void dispose() {
    _statesController.dispose();
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(10),
      child: TextField(
        controller: _controller,
        statesController: _statesController,
        decoration: InputDecoration(
          labelText: 'Enter something',
          border: OutlineInputBorder(
            borderSide: BorderSide(
              width: 2.0,
            ),
          ),
        ),
      ),
    );
  }
}

Flutter Engine Android OpenGL

As always, Flutter this time too, brings performance improvements by updating the Flutter engine. The key points below highlights Flutter Engine Android OpenGL improvements:

  • Almost all Android devices supported: Thanks to the focus on OpenGL, Impeller now covers nearly all Android devices, extending its reach beyond Vulkan’s 77% share.
  • MSAA for sharper visuals: The addition of Multisample Anti-Aliasing (MSAA) ensures smoother text and graphics, enhancing the visual quality of your Flutter apps.
  • Feature parity on the horizon: While a few features like custom shaders and full external texture support are still in progress, Impeller is rapidly approaching complete functionality on both Vulkan and OpenGL backends.

Android improvements

Flutter deep linking validator

deep linking validator has been added in Flutter 3.19 for android. Deep linking is when you’re browsing a website on your phone, and you click a link that takes you directly to a specific page in a mobile app. That’s deep linking, But sometimes, setting up deep linking can be tricky and frustrating.

This is where the new Deep Link Validator comes in. It’s like a helpful assistant that checks if your deep linking setup is working correctly. No more guessing or struggling!

The current version focuses on Android specifically. It basically looks at a file called “assetlinks.json”. This file tells the system how your app handles deep link

To use that Deep Link Validator

  1. Open Flutter DevTools, which is a handy debugging tool for Flutter apps.
  2. Click on the “Deep Links” tab.
  3. Import your Flutter project with deep links set up.
  4. The Validator checks your “assetlinks.json” file and tells you if everything is configured correctly.
flutter deep linking validator

Android default share button

The default Share button on text fields and views was previously missing from Android, but now it’s added in this release as part of the ongoing effort to ensure all the default context menu buttons are available on each platform.

flutter 3.19 version android defualt button

iOS improvements

Flutter iOS native fonts

  • More natural text spacing: Flutter now aligns with Apple’s design guidelines, using a tighter spacing for larger fonts instead of the previously used, wider spacing. This creates a more compact and visually balanced appearance that’s consistent with native iOS apps.
  • Enhanced readability: While tighter spacing might sound concerning, remember that Apple’s guidelines factor in mobile viewing distances. This subtle adjustment improves readability for larger text sizes, ensuring your content remains clear and accessible.
  • Default behavior change: This improvement is now the default behavior for Flutter apps on iOS.
flutter ios native fonts

Conclusion

There are more updates and improvements on DevTools, Windows Arm64 support, and some platforms are now deprecated in Flutter. In order to get familiar with everything checkout either Kevin Chisholm’s blogpost on Medium or latest release notes on Flutter 3.19.

At the end, a very big thanks to the intelligent flutter official team and the hardworking community members who’s proving us right for choosing flutter for app development and as a professional career choice.

Thanks for being in touch with me until now, follow me in order to be updated with comprehensive flutter latest updates.

Leave a Comment

Your email address will not be published. Required fields are marked *

Muhammad Adnan

Muhammad Adnan

Adnan Khan is a Sr. Flutter Full-Stack Developer at ETechViral, known for his mastery in building Android and iOS applications using Firebase and Node.js. Adnan shares his extensive knowledge through YouTube videos and blog posts, making complex concepts accessible to all.

Related Blogs

Converting JSON to Dart: The Ultimate Guide

In Flutter app development, seamlessly integrating JSON data into Dart code is crucial for building efficient, high-performing applications. This guide provides a comprehensive look at

Scroll to Top

Apply for Sales & Marketing

Company Description

eTechViral is a leading tech company with a team of skilled professionals specializing in developing customized software solutions from design to development. We prioritize client relationships, quality deliverables, and a compassionate exchange of energy.


Role & Responsibilities

This is a full-time remote role for a Sales and Marketing Specialist. The Sales and Marketing Specialist will be responsible for developing and implementing sales and marketing strategies, maintaining customer relationships, providing training to sales team members, and managing sales operations.

Role & Responsibilities

  • Excellent communication and customer service skills
  • Demonstrated ability to drive sales and meet quotas
  • Experience in sales management and operation
  • Ability to provide training to sales team members
  • Bachelor’s degree in Marketing, Business Administration or related field
  • Knowledge of virtual sales and marketing tools is a plus
  • Ability to work independently and remotely
eTechviral-logo

Welcome to eTechviral