<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: TheOtherDev/s</title>
    <description>The latest articles on Forem by TheOtherDev/s (@theotherdevs).</description>
    <link>https://forem.com/theotherdevs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F458126%2F1228fd0f-0c1d-4d1e-b59b-1e4b49980df6.png</url>
      <title>Forem: TheOtherDev/s</title>
      <link>https://forem.com/theotherdevs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/theotherdevs"/>
    <language>en</language>
    <item>
      <title>Getting to know Flutter: Local notifications</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 12 Jan 2022 16:40:50 +0000</pubDate>
      <link>https://forem.com/theotherdevs/getting-to-know-flutter-local-notifications-411l</link>
      <guid>https://forem.com/theotherdevs/getting-to-know-flutter-local-notifications-411l</guid>
      <description>&lt;p&gt;While your app can be fine without advanced ways to build your users' loyalty, &lt;strong&gt;notifications&lt;/strong&gt; are a really important feature that you should consider implementing. It can be a reminder on how much you love your users or a way to remind them of important events. Well, in Flutter using this great tool is &lt;strong&gt;pretty easy&lt;/strong&gt; but you need to know a few concepts to master it! In this tutorial we'll see how to create a simple notification and a scheduled one.&lt;/p&gt;

&lt;h2&gt;
  
  
  flutter_local_notifications
&lt;/h2&gt;

&lt;p&gt;This is the plugin we'll use and it's the most popular one on pub.dev. You can find it &lt;a href="https://pub.dev/packages/flutter_local_notifications" rel="noopener noreferrer"&gt;here&lt;/a&gt; and add it easily to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies:
  flutter_local_notifications: ^9.1.5

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This plugin supports iOS and Android and can show pretty much whatever you want as you were developing on native platform. Before starting with Dart code we'll need to check specific configuration for &lt;a href="https://pub.dev/packages/flutter_local_notifications#-ios-setup" rel="noopener noreferrer"&gt;iOS&lt;/a&gt; and &lt;a href="https://pub.dev/packages/flutter_local_notifications#-ios-setup" rel="noopener noreferrer"&gt;Android&lt;/a&gt;. Also let's add &lt;a href="https://pub.dev/packages/flutter_native_timezone" rel="noopener noreferrer"&gt;this package&lt;/a&gt; too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter_native_timezone: ^2.0.0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this we can schedule timed notifications without caring for the timezones of the device.&lt;/p&gt;

&lt;p&gt;A simple notification&lt;/p&gt;

&lt;p&gt;Let's do an easy "hello world"! First we need to initialize the plugin with iOS and Android specifications. For Android we'll need to specify the channel and the icon. The channel can be initialized directly but the icon need to be added to the initialization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  static const AndroidNotificationDetails _androidNotificationDetails =
  AndroidNotificationDetails(
    'MYID',
    'NOTIFICATION',
    channelDescription: 'Description',
    playSound: true,
    priority: Priority.high,
    importance: Importance.high,
  );

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Future&amp;lt;void&amp;gt; init() async {
    final AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;iOS initialization is pretty straightforward too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final IOSInitializationSettings initializationSettingsIOS =
        const IOSInitializationSettings(
      requestSoundPermission: false,
      requestBadgePermission: false,
      requestAlertPermission: false,
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also we want to init "Timezones" plugin. The final code for initialization will result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

Future&amp;lt;void&amp;gt; init() async {
    final AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');

    final IOSInitializationSettings initializationSettingsIOS =
        const IOSInitializationSettings(
      requestSoundPermission: false,
      requestBadgePermission: false,
      requestAlertPermission: false,
    );

    final InitializationSettings initializationSettings =
        InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
      macOS: null,
    );

    tz.initializeTimeZones();

    await flutterLocalNotificationsPlugin.initialize(
      initializationSettings,
    );
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can do that in a initState() without much issues. Also we'll need to ask for notifications permission on iOS this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final bool result = await flutterLocalNotificationsPlugin
    .resolvePlatformSpecificImplementation&amp;lt;
        IOSFlutterLocalNotificationsPlugin&amp;gt;()
    ?.requestPermissions(
    alert: true,
    badge: true,
    sound: true,
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that we are ready to trigger a notification!&lt;/p&gt;

&lt;p&gt;Then we can finally create our notification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const NotificationDetails platformChannelSpecifics =
                NotificationDetails(android: _androidNotificationDetails);
            await flutterLocalNotificationsPlugin.show(
              Random().nextInt(9000),
//NOTIFICATION ID - SHOULD BE UNIQUE/RANDOM
              'Hello',
              'World!',
              platformChannelSpecifics,
            );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result will be this:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyvkpnhdpa4fp4z0nhln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnyvkpnhdpa4fp4z0nhln.png" alt="Notification image"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Scheduled notification
&lt;/h2&gt;

&lt;p&gt;Scheduling a notification requires the same things as above but also a date time. It's best here to use directly Timezone plugin as it will take care of pretty much everything. We are now scheduling a notification to 5 seconds in the future:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var tzDateTime = tz.TZDateTime.now(tz.local).add(const Duration(seconds: 5));

            await flutterLocalNotificationsPlugin.zonedSchedule(
              0,
              'Scheduled Hello',
              'Scheduled World!',
              tzDateTime,
              platformChannelSpecifics,
              androidAllowWhileIdle: true,
              uiLocalNotificationDateInterpretation:
                  UILocalNotificationDateInterpretation.absoluteTime,
            );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  In conclusion
&lt;/h2&gt;

&lt;p&gt;Local notifications ca be a bit hard to initialize but they are a breeze to use once we understand them. This plugin offers a lot of options to customize notifications like media embedding and selection behavior but I'll leave them to you to discover!&lt;/p&gt;

&lt;p&gt;For more awesome Flutter tutorials check out &lt;a href="https://theotherdevs.com/getting-to-know-flutter/" rel="noopener noreferrer"&gt;our website&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Mastering Flutter: Bluetooth use</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 22 Dec 2021 16:05:32 +0000</pubDate>
      <link>https://forem.com/theotherdevs/mastering-flutter-bluetooth-use-m7</link>
      <guid>https://forem.com/theotherdevs/mastering-flutter-bluetooth-use-m7</guid>
      <description>&lt;p&gt;Let's face it, we are living in a &lt;strong&gt;connected world&lt;/strong&gt; in which also physical objects can be used with software. Today we are going to dive into this world by looking at one of the most common ways to connect to devices: &lt;strong&gt;bluetooth&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  flutter_blue
&lt;/h2&gt;

&lt;p&gt;To enable &lt;strong&gt;bluetooth&lt;/strong&gt; connectivity with your &lt;strong&gt;Flutter&lt;/strong&gt; app you should consider using &lt;a href="https://pub.dev/packages/flutter_blue"&gt;this package&lt;/a&gt; as it is the most used one. You can obviously create a custom plugin if you have specific needs but this one will be ok for most cases.&lt;/p&gt;

&lt;p&gt;To start add it to your &lt;code&gt;pubspec.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter_blue: ^0.8.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then add these permissions for &lt;code&gt;Android&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;uses-permission android:name="android.permission.BLUETOOTH" /&amp;gt;
  &amp;lt;uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /&amp;gt;
  &amp;lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also in the &lt;code&gt;ios&lt;/code&gt;/Runner/Info.plist add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;dict&amp;gt;
     &amp;lt;key&amp;gt;NSBluetoothAlwaysUsageDescription&amp;lt;/key&amp;gt;
     &amp;lt;string&amp;gt;Need BLE permission&amp;lt;/string&amp;gt;
     &amp;lt;key&amp;gt;NSBluetoothPeripheralUsageDescription&amp;lt;/key&amp;gt;
     &amp;lt;string&amp;gt;Need BLE permission&amp;lt;/string&amp;gt;
     &amp;lt;key&amp;gt;NSLocationAlwaysAndWhenInUseUsageDescription&amp;lt;/key&amp;gt;
     &amp;lt;string&amp;gt;Need Location permission&amp;lt;/string&amp;gt;
     &amp;lt;key&amp;gt;NSLocationAlwaysUsageDescription&amp;lt;/key&amp;gt;
     &amp;lt;string&amp;gt;Need Location permission&amp;lt;/string&amp;gt;
     &amp;lt;key&amp;gt;NSLocationWhenInUseUsageDescription&amp;lt;/key&amp;gt;
     &amp;lt;string&amp;gt;Need Location permission&amp;lt;/string&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For location permissions on iOS see more at: &lt;a href="https://developer.apple.com/documentation/corelocation/requesting_authorization_for_location_services"&gt;https://developer.apple.com/documentation/corelocation/requesting_authorization_for_location_services&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;The main goal of a bluetooth connection is to &lt;strong&gt;connect to a device&lt;/strong&gt;, discover its services and write/read data from it. First thing first we need to find our device so let's do a good old &lt;strong&gt;scan&lt;/strong&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FlutterBlue flutterBlue = FlutterBlue.instance;
flutterBlue.startScan(timeout: Duration(seconds: 4));

// Listen to scan results
var subscription = flutterBlue.scanResults.listen((results) {
    for (ScanResult r in results) {
           if(r.uuid == [YOUR DEVICE ID]){
               // Connect to the device
               await r.device.connect();

               // Disconnect from device
               r.device.disconnect();
           }
    }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; To stop just&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutterBlue.stopScan();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While you should not connect-disconnect so quickly you can see that doing it is a piece of cake.&lt;/p&gt;

&lt;p&gt;When you are connected then you should &lt;strong&gt;discover device services&lt;/strong&gt; this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;BluetoothService&amp;gt; services = await device.discoverServices();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, as each service has n &lt;strong&gt;characteristics&lt;/strong&gt;, you can check all of them this way;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var characteristics = service.characteristics;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With characteristics then you can pretty much do whatever you want like &lt;strong&gt;read or write&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List&amp;lt;int&amp;gt; value = await characteristic.read();
await characteristic.write([0x12, 0x34])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can do the same with the &lt;strong&gt;characteristic descriptors&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var descriptors = characteristic.descriptors;

List&amp;lt;int&amp;gt; value = await descriptor.read();
await descriptor.write([0x12, 0x34])

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last, but not least, we can also &lt;strong&gt;listen to characteristics changes&lt;/strong&gt; this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await characteristic.setNotifyValue(true);
characteristic.value.listen((value) {
    // do something with new value
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;There you are, you can now work with bluetooth on &lt;strong&gt;Flutter&lt;/strong&gt;. Be aware that Android and iOS behaviors can be a bit different, for example Android tends to cache manufacturer data so you should add "&lt;code&gt;allowDuplicates&lt;/code&gt;" to obtain them always. Feel free to explore and experiment!&lt;/p&gt;

&lt;p&gt;Want to check more awesome Flutter tutorials? &lt;a href="https://theotherdevs.com/mastering-flutter/"&gt;Click here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>dart</category>
    </item>
    <item>
      <title>Starting with Flutter: Asset usage on app</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Thu, 09 Dec 2021 16:05:57 +0000</pubDate>
      <link>https://forem.com/theotherdevs/starting-with-flutter-asset-usage-on-app-ipj</link>
      <guid>https://forem.com/theotherdevs/starting-with-flutter-asset-usage-on-app-ipj</guid>
      <description>&lt;p&gt;If your app needs some kind of graphics or file to work, your best option is to add assets to your application. With assets you can have images, audio, fonts and videos inside your flutter app. The great thing is that adding them is pretty easy and retrieving them is still a breeze!&lt;/p&gt;

&lt;h3&gt;
  
  
  Pubspec.yaml
&lt;/h3&gt;

&lt;p&gt;Every asset must be nominated into the project &lt;code&gt;pubspec.yaml&lt;/code&gt; file. Fortunately you don't need to add every file singularly but you can write down only the folder in which there is. To add them you should write down this under the "flutter" section of the &lt;code&gt;pubspec.yaml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flutter:
  assets:
    - myfolder/
    - myfolder/myGraphics
    - myfolder2/myGraphics2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The path always starts from the main folder of the project so you only need to add the relative one. &lt;/p&gt;

&lt;h3&gt;
  
  
  Retrieving assets
&lt;/h3&gt;

&lt;p&gt;Widgets should &lt;strong&gt;expose methods&lt;/strong&gt; to use assets, like Image does (&lt;code&gt;Image.asset("PATH")&lt;/code&gt;). The path to add is the absolute one starting from the project directory with the file name at the end with the extension. Considering the example above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Image.asset('assets/myfolder/image.png')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Some tricks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Create a function which will get a file name and will return the full asset path with the file at the end.&lt;/li&gt;
&lt;li&gt;  Use the iOS typical folder structure, Flutter will retrieve automatically the correct asset.

&lt;ul&gt;
&lt;li&gt;  Use the default folder for 1.0x then add 2.0x and 3.0x assets&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;  You can add custom fonts to assets folder, files... It's not only for audio and images. Remember always to add additional folders/files to the &lt;code&gt;pubspec.yaml&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Mastering Flutter: Custom Scrollview</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 24 Nov 2021 16:09:29 +0000</pubDate>
      <link>https://forem.com/theotherdevs/mastering-flutter-custom-scrollview-44m5</link>
      <guid>https://forem.com/theotherdevs/mastering-flutter-custom-scrollview-44m5</guid>
      <description>&lt;p&gt;In this tutorial you will learn how to achieve custom scrolling effects with the &lt;a href="https://api.flutter.dev/flutter/widgets/CustomScrollView-class.html"&gt;CustomScrollView&lt;/a&gt; widget and its sliver. Custom scroll views are particularly useful if you want to develop particular scrolling effects or if you want to have more control on the scrolling content of your ScrollView.&lt;/p&gt;

&lt;p&gt;So, what is a Sliver? From the documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A sliver is a portion of a scrollable area. You can use slivers to achieve custom scrolling effects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Slivers are particular widgets that must produce &lt;a href="https://api.flutter.dev/flutter/widgets/rendering/RenderSliver-class.html"&gt;RenderSliver&lt;/a&gt; objects and are the children of the CustomScrollView.&lt;/p&gt;

&lt;p&gt;Both ListViews and GridViews uses a CustomScrollView and slivers widgets under the hood.&lt;/p&gt;

&lt;p&gt;Here's some useful Sliver provided by Flutter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://api.flutter.dev/flutter/material/SliverAppBar-class.html"&gt;SliverAppBar&lt;/a&gt;: this sliver renders an app bar, it is typically used as the first child of the custom scroll. It can be configured to change its height according to the scrolling of the user.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://api.flutter.dev/flutter/widgets/SliverGrid-class.html"&gt;SliverGrid&lt;/a&gt;: a sliver that renders a grid of widgets&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://api.flutter.dev/flutter/widgets/SliverList-class.html"&gt;SliverList&lt;/a&gt; and &lt;a href="https://api.flutter.dev/flutter/widgets/SliverFixedExtentList-class.html"&gt;SliverFixedExtentList&lt;/a&gt;: slivers that render a list inside the scrollview. The fixed extent version of the list is more efficient because it doesn't need to calculate the height/width of its children&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://api.flutter.dev/flutter/widgets/SliverToBoxAdapter-class.html"&gt;SliverToBoxAdapter&lt;/a&gt;: a sliver that contains a box widget, it's useful if you want to embed a widget inside a custom scroll view&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://api.flutter.dev/flutter/widgets/SliverPadding-class.html"&gt;SliverPadding&lt;/a&gt;: a sliver that applies padding to another sliver.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's build our first custom scroll view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;CustomScrollView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;slivers:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Widget&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;[&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SliverAppBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;pinned:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;expandedHeight:&lt;/span&gt; &lt;span class="mf"&gt;250.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;flexibleSpace:&lt;/span&gt; &lt;span class="n"&gt;FlexibleSpaceBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Custom Scroll View'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
            &lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;SliverGrid&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;gridDelegate:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SliverGridDelegateWithMaxCrossAxisExtent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;maxCrossAxisExtent:&lt;/span&gt; &lt;span class="mf"&gt;200.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;mainAxisSpacing:&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;crossAxisSpacing:&lt;/span&gt; &lt;span class="mf"&gt;10.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;childAspectRatio:&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;delegate:&lt;/span&gt; &lt;span class="n"&gt;SliverChildBuilderDelegate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
              &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;alignment:&lt;/span&gt; &lt;span class="n"&gt;Alignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;amber&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="si"&gt;$index&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;
              &lt;span class="o"&gt;},&lt;/span&gt;
              &lt;span class="nl"&gt;childCount:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;SliverFixedExtentList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;itemExtent:&lt;/span&gt; &lt;span class="mf"&gt;50.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;delegate:&lt;/span&gt; &lt;span class="n"&gt;SliverChildBuilderDelegate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
              &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;alignment:&lt;/span&gt; &lt;span class="n"&gt;Alignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;' &lt;/span&gt;&lt;span class="si"&gt;$index&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                &lt;span class="o"&gt;);&lt;/span&gt;
              &lt;span class="o"&gt;},&lt;/span&gt;
            &lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple scrollview with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An app bar at the top&lt;/li&gt;
&lt;li&gt;A grid &lt;/li&gt;
&lt;li&gt;A List&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the result is the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cdn.mburger.cloud/332955/Simulator-Screen-Recording---iPhone-13-Pro---2021-11-24-at-15.42.46.mp4?data=eyJtZWRpYV9pZCI6MzMyOTU1LCJieXRlcyI6MTcyMDkzMSwicHJvamVjdF9pZCI6MTE5MiwiaGFzX2ltZ2l4IjowfQ%3D%3D"&gt;Check it out here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  NotificationListener and ScrollNotification
&lt;/h2&gt;

&lt;p&gt;Other widgets particularly useful when using custom scroll views are &lt;a href="https://api.flutter.dev/flutter/widgets/NotificationListener-class.html"&gt;NotificationListener&lt;/a&gt; &lt;a href="https://api.flutter.dev/flutter/widgets/ScrollNotification-class.html"&gt;ScrollNotification&lt;/a&gt;, you can use this widget to receive events when the user scrolls without using a ScrollController.&lt;/p&gt;

&lt;p&gt;Let's wrap our CustomScrollView inside a NotificationListener:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;NotificationListener&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ScrollNotification&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;onNotification:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;CustomScrollView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now whenever the user interacts with the scroll view the onNotification callback will be invoked with a ScrollNotification, you can use the information of the notification to change the layout of the widgets, or to manage your data.&lt;br&gt;
You could load more data when the user reaches the end of the content of the scroll view). &lt;br&gt;
Let's implement it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;          &lt;span class="nl"&gt;onNotification:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;ScrollEndNotification&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
              &lt;span class="c1"&gt;// We use 20 as our threshold to load more data&lt;/span&gt;
              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;extentAfter&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Load more data'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
              &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
          &lt;span class="o"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you wish to check out more awesome tutorials click &lt;a href="https://theotherdevs.com/mastering-flutter/"&gt;here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>dart</category>
    </item>
    <item>
      <title>Starting with Flutter: JSON &amp; Serialization</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 10 Nov 2021 16:05:38 +0000</pubDate>
      <link>https://forem.com/theotherdevs/starting-with-flutter-json-serialization-k64</link>
      <guid>https://forem.com/theotherdevs/starting-with-flutter-json-serialization-k64</guid>
      <description>&lt;p&gt;JSON is a great format to pass data through web and more. Every developer will be facing this dreaded issue: how the **** do I translate a JSON into an object? We are now here to check what Flutter gives us to serialize JSON objects. For the sake of this article we'll consider serializing an "Event" object composed like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Manual serialization
&lt;/h3&gt;

&lt;p&gt;Manual serialization is natively supported by Dart with the &lt;code&gt;dart:convert&lt;/code&gt; library. On our data class we'll need to create 2 functions called &lt;code&gt;fromJson&lt;/code&gt; and &lt;code&gt;toJson&lt;/code&gt; which, respectevely, will translate a json into our Event and vice versa. &lt;code&gt;fromJson&lt;/code&gt; takes a &lt;code&gt;Map&amp;lt;String, dynamic&lt;/code&gt;&amp;gt; and will give you an instance of the data class, &lt;code&gt;toJson&lt;/code&gt; is a class function which gives a Map starting from data parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;Event&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; 
        &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'title'&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'date'&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'imageUrl'&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;

  &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s"&gt;'title'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;'date'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="s"&gt;'imageUrl'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;imageUrl&lt;/span&gt;
    &lt;span class="o"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then serialize and deserialize is an easy line of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;//JSON String to a map&lt;/span&gt;
&lt;span class="n"&gt;Map&lt;/span&gt; &lt;span class="n"&gt;eventMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonDecode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonString&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//Serialize to object&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventMap&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//Encode to JSON String&lt;/span&gt;
&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonEncode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is easy but be aware that you would probably have also to face more complex objects (like nested JSONs) or you could wish for a more "automatic" way to to this operation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code generation libraries
&lt;/h3&gt;

&lt;p&gt;We'll see a very useful package called &lt;a href="https://pub.dev/packages/json_serializable"&gt;json_serializable&lt;/a&gt;, published by Google, which automatically generates code to serialize and deserialize our data class.&lt;/p&gt;

&lt;p&gt;First we need to add our dependencies, we'll need to add also dev_dependencies because there will be code generation from json_serializable that we don't want on our build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;dependencies:&lt;/span&gt;
  &lt;span class="nl"&gt;json_annotation:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;latest_version&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nl"&gt;dev_dependencies:&lt;/span&gt;
  &lt;span class="nl"&gt;build_runner:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;latest_version&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nl"&gt;json_serializable:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;latest_version&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then on our Event class we'll need to say that's a json_serializable class using annotations and allow the class to access private members in generated files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:json_annotation/json_annotation.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;/// This allows the class to access private members in&lt;/span&gt;
&lt;span class="c1"&gt;/// the generated file called *.g.dart, where the star denotes the source file name.&lt;/span&gt;
&lt;span class="kn"&gt;part&lt;/span&gt; &lt;span class="s"&gt;'event.g.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;/// An annotation for the code generator to know that this class needs&lt;/span&gt;
&lt;span class="c1"&gt;/// JSON serialization.&lt;/span&gt;
&lt;span class="nd"&gt;@JsonSerializable&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;/// A necessary factory constructor for creating a new Event instance&lt;/span&gt;
  &lt;span class="c1"&gt;/// from a map. Pass the map to the generated `_$EventFromJson()` constructor.&lt;/span&gt;
  &lt;span class="c1"&gt;/// The constructor is named after the source class Event.&lt;/span&gt;
  &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_$EventFromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;/// `toJson` is the convention for a class to declare support for serialization&lt;/span&gt;
  &lt;span class="c1"&gt;/// to JSON. The implementation simply calls the private, generated&lt;/span&gt;
  &lt;span class="c1"&gt;/// helper method `_$EventToJson`.&lt;/span&gt;
  &lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_$EventToJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate code for encoding and decoding all parameters in this class. You can change the name the decoding will find by adding an annotation to the parameter this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;//On the json it's 'event_image_url'&lt;/span&gt;

&lt;span class="nd"&gt;@JsonKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'event_image_url'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also set some defaults, required elements or to ignore some fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@JsonKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;defaultValue:&lt;/span&gt; &lt;span class="s"&gt;'NoTitle'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@JsonKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;required:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@JsonKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;ignore:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;imageUrl&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last passage is to run a command to generate JSON serialization code with a watcher that, is some data classes change, also the serialization code will be recreated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Run on project root&lt;/span&gt;
&lt;span class="n"&gt;flutter&lt;/span&gt; &lt;span class="n"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;build_runner&lt;/span&gt; &lt;span class="n"&gt;watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the end we'll just have to call our dear old &lt;code&gt;jsonDecode&lt;/code&gt; and &lt;code&gt;fromJson&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Map&lt;/span&gt; &lt;span class="n"&gt;eventMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonDecode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jsonString&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eventMap&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jsonEncode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;If your class have a nested class you'll need to JsonSerialize also the nested class and on your "father class" you'll need to change this annotation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@JsonSerializable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;explicitToJson:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;//Our class (already json_serialized)&lt;/span&gt;
  &lt;span class="n"&gt;Address&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. It may seem not the easiest thing in the world but it's better than doing it manually, also if you change something on your object you don't need to change the way the serialization works, you'll just need to redo the command or let the watcher do it. Pretty handy!&lt;/p&gt;

&lt;p&gt;Discover more awesome Flutter tutorials &lt;a href="https://theotherdevs.com/starting-with-flutter/"&gt;here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>tutorial</category>
      <category>begi</category>
    </item>
    <item>
      <title>Starting with Flutter: How to embed a webview</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 27 Oct 2021 15:31:55 +0000</pubDate>
      <link>https://forem.com/theotherdevs/starting-with-flutter-how-to-embed-a-webview-5g91</link>
      <guid>https://forem.com/theotherdevs/starting-with-flutter-how-to-embed-a-webview-5g91</guid>
      <description>&lt;p&gt;In this tutorial you will learn how to use &lt;code&gt;WebViews&lt;/code&gt; in your Flutter application. With WebViews you can embed web contents inside your app. We will use the &lt;a href="https://pub.dev/packages/webview_flutter"&gt;webview_flutter&lt;/a&gt; package that uses native WebViews (&lt;a href="https://developer.apple.com/documentation/webkit/wkwebview"&gt;WKWebView&lt;/a&gt; on iOS and &lt;a href="https://developer.android.com/reference/android/webkit/WebView"&gt;WebView &lt;/a&gt;on Android).&lt;/p&gt;

&lt;p&gt;The first thing that you have to do is to add the package to your &lt;code&gt;pubspec.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;dependencies:&lt;/span&gt;
  &lt;span class="nl"&gt;flutter:&lt;/span&gt;
    &lt;span class="nl"&gt;sdk:&lt;/span&gt; &lt;span class="n"&gt;flutter&lt;/span&gt;
  &lt;span class="nl"&gt;cupertino_icons:&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="nl"&gt;webview_flutter:&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;2.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this run &lt;code&gt;flutter pub get&lt;/code&gt;, or use the Pub get button.&lt;/p&gt;

&lt;p&gt;Now create a new file &lt;code&gt;webview_scaffold.dart&lt;/code&gt;, and create a new &lt;code&gt;StatefulWidget&lt;/code&gt; called &lt;code&gt;WebViewScaffold&lt;/code&gt;. &lt;br&gt;
Adding a WebView is very simple, we will need to use the &lt;code&gt;WebView&lt;/code&gt; Widget as the body of the Scaffold. In the following example the WebView will open &lt;a href="https://google.com"&gt;&lt;code&gt;https://google.com&lt;/code&gt;&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:webview_flutter/webview_flutter.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WebViewScaffold&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;WebViewScaffold&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WebViewScaffold&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_WebViewScaffoldState&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_WebViewScaffoldState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WebViewScaffold&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'WebView'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;WebView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;initialUrl:&lt;/span&gt; &lt;span class="s"&gt;'https://google.com'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;javascriptMode:&lt;/span&gt; &lt;span class="n"&gt;JavascriptMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unrestricted&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Navigation
&lt;/h2&gt;

&lt;p&gt;We can manage the navigation in our WebView, to do so we will use the &lt;code&gt;WebViewController&lt;/code&gt; object. This is created by the &lt;code&gt;WebView&lt;/code&gt; widget and passed in a callback that's called once the &lt;code&gt;WebView&lt;/code&gt; is created. &lt;br&gt;
Let's add the &lt;code&gt;WebViewController&lt;/code&gt; to our state and save it for later, when the callback is invoked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_WebViewScaffoldState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WebViewScaffold&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;WebViewController&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'WebView'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;WebView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;initialUrl:&lt;/span&gt; &lt;span class="s"&gt;'https://google.com'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;javascriptMode:&lt;/span&gt; &lt;span class="n"&gt;JavascriptMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unrestricted&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onWebViewCreated:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
          &lt;span class="o"&gt;});&lt;/span&gt;
        &lt;span class="o"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we just need to use the controller to make thee &lt;code&gt;WebView&lt;/code&gt; go back, go forward or reload. The &lt;code&gt;WebViewController&lt;/code&gt; has functions to go back, forward, reload and to check if the &lt;code&gt;WebView&lt;/code&gt; can go back or go forward. &lt;br&gt;
We will put those buttons in a &lt;code&gt;BottomAppBar&lt;/code&gt; as the &lt;code&gt;bottomNavigationBar&lt;/code&gt; of our &lt;code&gt;Scaffold&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:webview_flutter/webview_flutter.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WebViewScaffold&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;WebViewScaffold&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WebViewScaffold&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_WebViewScaffoldState&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_WebViewScaffoldState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WebViewScaffold&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;WebViewController&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'WebView'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;WebView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;initialUrl:&lt;/span&gt; &lt;span class="s"&gt;'https://google.com'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;javascriptMode:&lt;/span&gt; &lt;span class="n"&gt;JavascriptMode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unrestricted&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onWebViewCreated:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
          &lt;span class="o"&gt;});&lt;/span&gt;
        &lt;span class="o"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;onPageFinished:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;{});&lt;/span&gt;
        &lt;span class="o"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;bottomNavigationBar:&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
          &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_WebViewNavigationBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt;&lt;span class="o"&gt;!)&lt;/span&gt;
          &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_WebViewNavigationBar&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;WebViewController&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;_WebViewNavigationBar&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;
    &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;BottomAppBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;IconTheme&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;IconThemeData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
              &lt;span class="n"&gt;FutureBuilder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;future:&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;canGoBack&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
                &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;IconButton&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;arrow_back&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                  &lt;span class="nl"&gt;onPressed:&lt;/span&gt;
                      &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;goBack&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="o"&gt;),&lt;/span&gt;
              &lt;span class="o"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;FutureBuilder&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;future:&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;canGoForward&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
                &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;IconButton&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;arrow_forward&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                  &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
                      &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;goForward&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                      &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="o"&gt;),&lt;/span&gt;
              &lt;span class="o"&gt;),&lt;/span&gt;
              &lt;span class="n"&gt;Expanded&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;()),&lt;/span&gt;
              &lt;span class="n"&gt;IconButton&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refresh&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reload&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
              &lt;span class="o"&gt;),&lt;/span&gt;
            &lt;span class="o"&gt;],&lt;/span&gt;
          &lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>dart</category>
      <category>flutter</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Starting with Flutter: Sound nullsafety</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 13 Oct 2021 15:19:05 +0000</pubDate>
      <link>https://forem.com/theotherdevs/starting-with-flutter-sound-nullsafety-18fn</link>
      <guid>https://forem.com/theotherdevs/starting-with-flutter-sound-nullsafety-18fn</guid>
      <description>&lt;p&gt;Flutter 2 has landed few months ago and one of the key feature of the release were &lt;strong&gt;Null Safety.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Null safety it's an huge upgrade, to start migrating, inside the &lt;code&gt;pubspec.yaml&lt;/code&gt; file, change the sdk minimum to &lt;strong&gt;2.12.0:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nl"&gt;environment:&lt;/span&gt;
  &lt;span class="nl"&gt;sdk:&lt;/span&gt; &lt;span class="s"&gt;"&amp;gt;=2.12.0&amp;lt;3.0.0"&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then in the terminal run the following commands to regenerate the package configuration file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;flutter clean&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flutter pub get&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you'll have pretty much all the code broken, don't worry (or maybe yes :)), it's normal. Let's see now how your world will change:&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependencies
&lt;/h3&gt;

&lt;p&gt;You can still use non-null safety dependencies in your project but you should absolutely consider to update them as soon as possible. If a dependency needs dart &lt;strong&gt;SDK &amp;lt; 2.12&lt;/strong&gt; it will be not usable anymore. To check on updates and which package needs to do implement &lt;strong&gt;null safety&lt;/strong&gt; you can use this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;dart&lt;/span&gt; &lt;span class="nx"&gt;pub&lt;/span&gt; &lt;span class="nx"&gt;outdated&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;safety&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will see if your packages are null safety ready or if they need some updates.&lt;/p&gt;

&lt;h3&gt;
  
  
  "required"
&lt;/h3&gt;

&lt;p&gt;You are already accustomed to the &lt;code&gt;@required&lt;/code&gt; keyword which will create a warning if a parameter is missing from a constructor, right? The new &lt;strong&gt;required&lt;/strong&gt; keyword workd pretty similarly but it will show an &lt;strong&gt;error&lt;/strong&gt; on compiler so you'll never miss a "required" anymore.&lt;/p&gt;

&lt;h3&gt;
  
  
  "?" &amp;amp; "!"
&lt;/h3&gt;

&lt;p&gt;Meet new "friends", the &lt;strong&gt;question mark&lt;/strong&gt; and &lt;strong&gt;exclamation mark&lt;/strong&gt;! The first one will label your class parameters as nullable and will warning you any time you try to use them without checking in if they are null. You can force-use a nullable parameter by adding a &lt;code&gt;!&lt;/code&gt; after the name of it. Also the ? will change how you will create classes. Let's see an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MyButton&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;StatelessWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyButton&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onTap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;azure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;manualPadding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;final&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;final&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;onTap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;final&lt;/span&gt; &lt;span class="nx"&gt;Color&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;final&lt;/span&gt; &lt;span class="nx"&gt;EdgeInsets&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;manualPadding&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;override&lt;/span&gt;
  &lt;span class="nx"&gt;Widget&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BuildContext&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//MY build...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this &lt;code&gt;MyButton&lt;/code&gt; class we can see that "&lt;code&gt;content&lt;/code&gt;" and "&lt;code&gt;onTap&lt;/code&gt;" are required, "&lt;code&gt;color&lt;/code&gt;" is not and "&lt;code&gt;manualPadding&lt;/code&gt;" is nullable. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;content&lt;/code&gt; and &lt;code&gt;onTap&lt;/code&gt; should always be valorized or the compiler will show an error.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;color&lt;/code&gt; is a parameter which, if not valorized while creating MyButton, will have "azure" as a color.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;manualPadding&lt;/code&gt; is a nullable parameter, so while creating our class we can absolutely set it as null.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you implement &lt;strong&gt;null safety&lt;/strong&gt; also many main widgets' parameters can be set as &lt;code&gt;null&lt;/code&gt; and you will receive warnings and errors by the compiler.&lt;/p&gt;

&lt;h3&gt;
  
  
  "late"
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;late&lt;/code&gt; keyword can be used if you are &lt;strong&gt;SURE&lt;/strong&gt; it will be valorized before using it because the compiler &lt;strong&gt;will not stop you&lt;/strong&gt; to use it, even if it is &lt;code&gt;null&lt;/code&gt; (and in this case it will throw an error while running). Also it will show you a warning if you try to check if it is null as... It SHOULD NOT BE NULL!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;late&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;allStrings&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wrapping all up
&lt;/h3&gt;

&lt;p&gt;Null safety is not very easy to digest but will improve your app performance and awareness to possible issues with your code. It can be very scary at the beginning but you will go through it. And if you're not ready... No hassle! You can still stick to non-null safey!&lt;/p&gt;

&lt;p&gt;Want to check more awesome Flutter tutorials? &lt;a href="https://theotherdevs.com/starting-with-flutter/"&gt;Click here!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Starting With Flutter: Bottom Bar</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 06 Oct 2021 15:14:03 +0000</pubDate>
      <link>https://forem.com/theotherdevs/starting-with-flutter-bottom-bar-3p3d</link>
      <guid>https://forem.com/theotherdevs/starting-with-flutter-bottom-bar-3p3d</guid>
      <description>&lt;p&gt;While buttons and menus are nice ways to let users navigate your app, you can also use &lt;strong&gt;Bottom Bars&lt;/strong&gt; to make it easier and more visually pleasing. iOS users are already well into the Bottom Bar world and the new Android design guidelines embrace it in full force so... Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  First steps
&lt;/h2&gt;

&lt;p&gt;The easiest way to create a BottomBar is from &lt;code&gt;Scaffold&lt;/code&gt; as it has a &lt;code&gt;bottomNavigationBar&lt;/code&gt; property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;_currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'My Demo'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;bottomNavigationBar:&lt;/span&gt; &lt;span class="n"&gt;BottomNavigationBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;currentIndex:&lt;/span&gt; &lt;span class="n"&gt;_currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;items:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;[&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;'Chiamate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;'Camera'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;'Chats'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'My Position: &lt;/span&gt;&lt;span class="si"&gt;$_currentIndex&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we can see that &lt;code&gt;BottomNavigationBar&lt;/code&gt; has 3 important properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;currentIndex&lt;/code&gt;: it is the current index of the bar. You can see it as the current focused element which should be shown.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onTap&lt;/code&gt;: called when you tap one of the BottomNavigationBar elements. Here most of the time goes the setState function which will change the currentIndex.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;items&lt;/code&gt;: a list of BottomNavigationBarItem which are convenient Widgets to show bar elements. They already manage "selected" and "unselected" states and show on appropriate colors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46o39p9aew5hnrav34nc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46o39p9aew5hnrav34nc.png" alt="Easy BottomNavigationBar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a really easy BottomBar that can be used to show different screens based on the &lt;strong&gt;_currentIndex&lt;/strong&gt;. &lt;code&gt;BottomNavigationBarItem&lt;/code&gt; explains by itself. Now let's see how to customize our BottomBar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's Customize!
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;BottomNavigationBar&lt;/code&gt; can be easily customized by using its properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;type&lt;/code&gt;: you can select between BottomNavigationBarType.shifting and BottomNavigationBarType.fixed. The first will highlight and center the selected tab, the second will fix the tab size and not enlarge them if selected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;backgroundColor&lt;/code&gt;: you can set a custom color to the background of the BottomNavigationBar&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;elevation&lt;/code&gt;: setting an elevation will cast a shadow on the BottomNavigationBar top part.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;showSelectedLabels, showUnselectedLabels&lt;/code&gt; : choose to show labels or not for different situations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stylize the single buttons it's a bit more tricky, you can use these BottomNavigationBar properties to change colors, size and label, also it can be useful to change the Theme of the items.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;selected/unselectedFontSize&lt;/code&gt;: takes a double to set text size.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;selected/unselectedItemColor&lt;/code&gt;: sets color of the icons&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;selected/unselectedIconTheme&lt;/code&gt;: takes a &lt;strong&gt;IconThemeData&lt;/strong&gt; object in which you can set how icons should appear&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;selected/unselectedLabelStyle&lt;/code&gt;: takes a &lt;strong&gt;TextStyle&lt;/strong&gt; object i which you can set how labels should appear.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To change more deeply the appaerance of the &lt;code&gt;BottomNavigationBar&lt;/code&gt; you can wrap it around a &lt;strong&gt;Theme&lt;/strong&gt; object.&lt;/p&gt;

&lt;p&gt;An example of a customized BottomNavigationBar can be something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm747nrx4y1gl2j2a203z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm747nrx4y1gl2j2a203z.png" alt="Customized bar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'My Demo'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;bottomNavigationBar:&lt;/span&gt; &lt;span class="n"&gt;BottomNavigationBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;type:&lt;/span&gt; &lt;span class="n"&gt;BottomNavigationBarType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;unselectedItemColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;selectedFontSize:&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;unselectedFontSize:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;showSelectedLabels:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;showUnselectedLabels:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;selectedLabelStyle:&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;unselectedLabelStyle:&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white24&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;selectedIconTheme:&lt;/span&gt; &lt;span class="n"&gt;IconThemeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;size:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;unselectedIconTheme:&lt;/span&gt; &lt;span class="n"&gt;IconThemeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;size:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;currentIndex:&lt;/span&gt; &lt;span class="n"&gt;_currentIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;selectedItemColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_currentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nl"&gt;items:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;[&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;call&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;'Chiamate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;camera&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;'Camera'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;BottomNavigationBarItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="n"&gt;Icon&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Icons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nl"&gt;label:&lt;/span&gt; &lt;span class="s"&gt;'Chats'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'My Position: &lt;/span&gt;&lt;span class="si"&gt;$_currentIndex&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There you are, this is a good BottomBar for your app!&lt;/p&gt;

&lt;p&gt;You can change a lot of things if you wish with a bit of effort, like adding animations or make a gradient background, but now it's up to you to create an awesome Bottom Bar!&lt;/p&gt;

&lt;p&gt;Wish to check more awesome tutorials? Click &lt;a href="https://theotherdevs.com/starting-with-flutter/" rel="noopener noreferrer"&gt;here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting to know Flutter: Advanced use of ModalBottomSheet</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 29 Sep 2021 15:03:28 +0000</pubDate>
      <link>https://forem.com/theotherdevs/getting-to-know-flutter-advanced-use-of-modalbottomsheet-1hjf</link>
      <guid>https://forem.com/theotherdevs/getting-to-know-flutter-advanced-use-of-modalbottomsheet-1hjf</guid>
      <description>&lt;p&gt;Do you want to present a simple modal picker to the user or just show a nice feedback to a user action? In this tutorial you will learn how to use the &lt;a href="https://api.flutter.dev/flutter/material/showModalBottomSheet.html"&gt;showModalBottomSheet&lt;/a&gt; function.&lt;/p&gt;

&lt;p&gt;Let's start by creating a simple bottom sheet,  with a text and a button. As you can see to close a modal bottom sheet you will use the &lt;code&gt;.pop()&lt;/code&gt; function of the Navigator, as you do when closing &lt;code&gt;Scaffold&lt;/code&gt; Widgets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ModalBottomSheetsPage&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;ModalBottomSheetsPage&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Modal bottom sheets'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Show modal bottom sheet'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_showBottomSheet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;_showBottomSheet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;showModalBottomSheet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;context:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SafeArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Padding&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;symmetric&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;vertical:&lt;/span&gt; &lt;span class="mf"&gt;20.0&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;mainAxisSize:&lt;/span&gt; &lt;span class="n"&gt;MainAxisSize&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;crossAxisAlignment:&lt;/span&gt; &lt;span class="n"&gt;CrossAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Widget&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;[&lt;/span&gt;
                &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                  &lt;span class="s"&gt;'This is a Modal bottom sheet!'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="n"&gt;Theme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;textTheme&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;headline4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;textAlign:&lt;/span&gt; &lt;span class="n"&gt;TextAlign&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="o"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Close BottomSheet'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                  &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Navigator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pop&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
                &lt;span class="o"&gt;)&lt;/span&gt;
              &lt;span class="o"&gt;],&lt;/span&gt;
            &lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's add some fanciness and sound the top corners of our bottom sheet, this is incredibly easy, you just need to add the &lt;code&gt;shape&lt;/code&gt; parameter to the &lt;code&gt;showModalBottomSheet&lt;/code&gt; function, specifying the shape that we want to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;    &lt;span class="n"&gt;showModalBottomSheet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;context:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;shape:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;RoundedRectangleBorder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;borderRadius:&lt;/span&gt; &lt;span class="n"&gt;BorderRadius&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;vertical&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;top:&lt;/span&gt; &lt;span class="n"&gt;Radius&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;circular&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SafeArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will do a more complex example, we will display in the bottom sheet a list of 100 elements, and the sheet will expand/collapse while the user scrolls through the list. To do so we will use the &lt;a href="https://api.flutter.dev/flutter/widgets/DraggableScrollableSheet-class.html"&gt;DraggableScrollableSheet&lt;/a&gt; widget.&lt;br&gt;&lt;br&gt;
This widget has been created to do this types of sheet, it has a builder function that exposes a &lt;code&gt;ScrollController&lt;/code&gt; that we will need to use in our ListView to keep the scrolling of the list in sync with the state of the bottom sheet.&lt;/p&gt;

&lt;p&gt;In this case we're also passing the index of the list tile pressed in the pop function, so we could use it later. It will be the result of the &lt;code&gt;Future&lt;/code&gt; of the &lt;code&gt;showModalBottomSheet&lt;/code&gt; function, and we're retrieving it awaiting on&lt;code&gt;showModalBottomSheet&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_showBottomSheet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;showModalBottomSheet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;context:&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;isScrollControlled:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;isDismissible:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;shape:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;RoundedRectangleBorder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;borderRadius:&lt;/span&gt; &lt;span class="n"&gt;BorderRadius&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;vertical&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;top:&lt;/span&gt; &lt;span class="n"&gt;Radius&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;circular&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DraggableScrollableSheet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;initialChildSize:&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;minChildSize:&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;maxChildSize:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;expand:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scrollController&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;SafeArea&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;scrollController&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;itemCount:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;itemBuilder:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ListTile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()),&lt;/span&gt;
              &lt;span class="nl"&gt;onTap:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Navigator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;pop&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
            &lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>flutter</category>
      <category>beginners</category>
      <category>dart</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting to know Flutter: Easy notifications with MBMessages</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 22 Sep 2021 15:05:00 +0000</pubDate>
      <link>https://forem.com/theotherdevs/getting-to-know-flutter-easy-notifications-with-mbmessages-5gjm</link>
      <guid>https://forem.com/theotherdevs/getting-to-know-flutter-easy-notifications-with-mbmessages-5gjm</guid>
      <description>&lt;p&gt;One of the most requested features when you develop an app are &lt;strong&gt;Push Notifications&lt;/strong&gt;. Those messages are an awesome way to &lt;strong&gt;engage&lt;/strong&gt; users with personalized content but may be a bit hard to implement "the good way". Here we want to show you how easy it is to implement on your Flutter application Push Notifications using the power of &lt;strong&gt;MBurger&lt;/strong&gt; and the &lt;strong&gt;MBMessages&lt;/strong&gt; library.&lt;/p&gt;

&lt;h3&gt;
  
  
  Initialize MBurger and add MBMessages
&lt;/h3&gt;

&lt;p&gt;If you haven't done it already check out our article about &lt;strong&gt;Pull to Refresh&lt;/strong&gt; to know &lt;a href="https://dev.to/theotherdevs/getting-to-know-flutter-pull-to-refresh-with-online-data-592i"&gt;how to create a new MBurger project&lt;/a&gt;. In a few words you'll need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register for free on MBurger&lt;/li&gt;
&lt;li&gt;Create a new project&lt;/li&gt;
&lt;li&gt;Create an API Key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are unsure on how to do these steps refer &lt;a href="https://docs.mburger.cloud/api-docs-1/introduction/getting-started" rel="noopener noreferrer"&gt;this guide&lt;/a&gt;. Once you've done all of this you have to add MBMessages dependency to your project. Head over to &lt;a href="https://pub.dev/packages/mbmessages" rel="noopener noreferrer"&gt;this page&lt;/a&gt; and add it as your dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;dependencies:&lt;/span&gt;
  &lt;span class="nl"&gt;mbmessages:&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First step completed, well done!&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure push notifications on MBurger
&lt;/h3&gt;

&lt;p&gt;Next we'll configure push notifications on our app. Let's return on &lt;strong&gt;MBurger&lt;/strong&gt; website and let's enable &lt;strong&gt;Push Notifications&lt;/strong&gt; on settings. Here you can also enable integrations with other systems real easily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funpkz3r78rkaxa3g1zjz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funpkz3r78rkaxa3g1zjz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5v5pps74unzc90lg9jm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs5v5pps74unzc90lg9jm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By enabling it a new menu called "&lt;strong&gt;Engagement&lt;/strong&gt;" on the left will appear. Here you'll have to configure &lt;strong&gt;MBurger&lt;/strong&gt; to use the &lt;strong&gt;MPush&lt;/strong&gt; subsystem in order to send Push Notifications.&lt;/p&gt;

&lt;p&gt;Click on it and then on "Settings".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5wop1u5o3dxkmga4u5t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu5wop1u5o3dxkmga4u5t.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this screen you'll see a generated token and two boxes, one for &lt;strong&gt;Android&lt;/strong&gt; and one for &lt;strong&gt;iOS&lt;/strong&gt;. You'll need to compile those boxes by linking your &lt;strong&gt;Firebase&lt;/strong&gt; and &lt;strong&gt;AppStore Connect&lt;/strong&gt; apps.&lt;/p&gt;

&lt;p&gt;For iOS you'll need to create an &lt;strong&gt;APNS API Key&lt;/strong&gt; (&lt;a href="https://docs.mpush.cloud/ios-sdk/add-push-notification-to-your-app" rel="noopener noreferrer"&gt;click here&lt;/a&gt; if you are not sure on how to achieve it), you'll also need to add your &lt;strong&gt;Apple Team ID&lt;/strong&gt; and &lt;strong&gt;App Bundle&lt;/strong&gt;. Once you have added all click on "Update". Be aware for the "Production" checkbox, if you're trying push notification on a development device keep this checkbox to off and enable it only one you'll go live.&lt;/p&gt;

&lt;p&gt;Then you have to modify the &lt;code&gt;AppDelegate&lt;/code&gt;class of your application, open &lt;code&gt;AppDelegate.swift&lt;/code&gt; file and add this line in the didFinishLaunchingWithOptions function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;UNUserNotificationCenter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;current&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app delegate should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UIKit&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flutter&lt;/span&gt;

&lt;span class="nd"&gt;@UIApplicationMain&lt;/span&gt;
&lt;span class="nd"&gt;@objc&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppDelegate&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FlutterAppDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;override&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nl"&gt;application:&lt;/span&gt; &lt;span class="n"&gt;UIApplication&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;didFinishLaunchingWithOptions&lt;/span&gt; &lt;span class="nl"&gt;launchOptions:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;UIApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LaunchOptionsKey&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;UNUserNotificationCenter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;current&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;
    &lt;span class="n"&gt;GeneratedPluginRegistrant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;with&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;application&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;didFinishLaunchingWithOptions:&lt;/span&gt; &lt;span class="n"&gt;launchOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Android side you'll need to create a &lt;strong&gt;Firebase&lt;/strong&gt; project and configure it (refer to &lt;a href="https://docs.ep.mburger.cloud/android-docs/messages/prerequisites-for-push-notifications" rel="noopener noreferrer"&gt;this guide&lt;/a&gt;). Lastly copy the &lt;code&gt;FCM server key&lt;/code&gt; onto MBurger and give it a good "Update".&lt;/p&gt;

&lt;p&gt;Remember for Android to add this to your project build.gradle file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;classpath&lt;/span&gt; &lt;span class="s"&gt;'com.google.gms:google-services:4.3.5'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and this to your app build.gradle&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;apply&lt;/span&gt; &lt;span class="nl"&gt;plugin:&lt;/span&gt; &lt;span class="s"&gt;'com.google.gms.google-services'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You are almost done, it's time to code!&lt;/p&gt;

&lt;h3&gt;
  
  
  Initialize MBMessages
&lt;/h3&gt;

&lt;p&gt;This is a really easy part. You'll need to initialize &lt;strong&gt;MBurger&lt;/strong&gt; and add &lt;strong&gt;MBMessages&lt;/strong&gt; as a plugin, so it can be initialized and you can instantaneously start receiving messages.&lt;/p&gt;

&lt;p&gt;Let's head over to your main widget and &lt;strong&gt;initialize MBurger&lt;/strong&gt; with your personal API Key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;runApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyApp&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;_MyAppState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_MyAppState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_MyAppState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MBManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MY_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MaterialApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s"&gt;'MBMessages'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;theme:&lt;/span&gt; &lt;span class="n"&gt;ThemeData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;primarySwatch:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;home:&lt;/span&gt; &lt;span class="n"&gt;MyHomePage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="s"&gt;'Flutter MBMessages'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way you'll have initialized &lt;strong&gt;MBurger&lt;/strong&gt;, now we need to add &lt;strong&gt;MBMessages&lt;/strong&gt; and initialize it with the key provided on MBurger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pushToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"MY_ENGAGEMENT_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;MBManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="p"&gt;()];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next you'll need to use &lt;code&gt;MBMessages.configurePush&lt;/code&gt; and implement these methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;onNotificationArrival&lt;/code&gt; -&amp;gt; called when a Push Notification arrives on your device&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;onNotificationTap&lt;/code&gt; -&amp;gt; called when a Push Notification is tapped&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lastly you'll need to set the &lt;code&gt;Android notification channel&lt;/code&gt; for push notifications. You should provide a &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;description&lt;/strong&gt; and &lt;strong&gt;id&lt;/strong&gt; for your channel as well as an icon stored in &lt;code&gt;drawable&lt;/code&gt; or &lt;code&gt;mipmap&lt;/code&gt; folders on Android part.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;configurePush&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;onNotificationArrival:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Notification arrived: &lt;/span&gt;&lt;span class="si"&gt;$notification&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nl"&gt;onNotificationTap:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Notification tapped: &lt;/span&gt;&lt;span class="si"&gt;$notification&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nl"&gt;androidNotificationsSettings:&lt;/span&gt; &lt;span class="n"&gt;MPAndroidNotificationsSettings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;channelId:&lt;/span&gt; &lt;span class="s"&gt;'messages_example'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;channelName:&lt;/span&gt; &lt;span class="s"&gt;'mbmessages'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;channelDescription:&lt;/span&gt; &lt;span class="s"&gt;'mbmessages'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;icon:&lt;/span&gt; &lt;span class="s"&gt;'@mipmap/ic_launcher'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next you'll need to implement the &lt;code&gt;onToken&lt;/code&gt; method found on &lt;strong&gt;MBMessages&lt;/strong&gt;. This is called when you register your device for receiving push notifications. You can easily then &lt;strong&gt;register to the topics&lt;/strong&gt; you want after it. &lt;strong&gt;MBMessages&lt;/strong&gt; provides already 2 "standard" topics, one for all users and one dedicated to single devices:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;projectPushTopic&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;devicePushTopic&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code for this step will result like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Token received &lt;/span&gt;&lt;span class="si"&gt;$token&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerDevice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerToTopics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;projectPushTopic&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
          &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;devicePushTopic&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Registered'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly you'll need to &lt;strong&gt;request a token&lt;/strong&gt; from Firebase and APNS, then if you followed this tutorial your device will be registered for push notifications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MBMessages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requestToken&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! You have set up push notifications!&lt;/p&gt;

&lt;h3&gt;
  
  
  Try it!
&lt;/h3&gt;

&lt;p&gt;Now it's time to check if everything is working properly! On MBurger click on &lt;strong&gt;Engagement&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Messages&lt;/strong&gt;. Create a new push message and see the magic unfolds!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj19smjnviit40qlzwxlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj19smjnviit40qlzwxlz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to go now?
&lt;/h3&gt;

&lt;p&gt;With MBMessage you can also create awesome in-app messages and handle Push Notifications in a more detailed way, check out the &lt;a href="https://pub.dev/packages/mbmessages" rel="noopener noreferrer"&gt;pub.dev page&lt;/a&gt; to know more!&lt;/p&gt;

&lt;p&gt;Wish to check on more awesome Flutter tutorials? &lt;a href="https://theotherdevs.com/getting-to-know-flutter/" rel="noopener noreferrer"&gt;Click here&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>beginners</category>
      <category>dart</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Mastering Flutter: Animations Part 2</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Wed, 15 Sep 2021 14:58:42 +0000</pubDate>
      <link>https://forem.com/theotherdevs/mastering-flutter-animations-part-2-46fk</link>
      <guid>https://forem.com/theotherdevs/mastering-flutter-animations-part-2-46fk</guid>
      <description>&lt;p&gt;This is the second part of a series of tutorials to build animations with Flutter. In this pat we will learn how to use the &lt;code&gt;Animations&lt;/code&gt; and &lt;code&gt;AnimationControllers&lt;/code&gt;, to build more precise animations.&lt;/p&gt;

&lt;p&gt;The final result will be like this video, you can find the asset of the image that we've used here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zqJ-6aHL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/voc5lebyjf4vzwokao8h.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zqJ-6aHL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/voc5lebyjf4vzwokao8h.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first thing that we need to do is to create our Ghost Widget that we will use to build the animation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Ghost&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatelessWidget&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Ghost&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;width:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asset&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;'images/ghost.png'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;fit:&lt;/span&gt; &lt;span class="n"&gt;BoxFit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contain&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, let's create a Stateful Widget that will represent our Scaffold, with the Ghost in the center of the screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:flutter/material.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'ghost.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AnimationsScaffold&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;AnimationsScaffold&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;})&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;key:&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;_AnimationsScaffoldState&lt;/span&gt; &lt;span class="n"&gt;createState&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_AnimationsScaffoldState&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_AnimationsScaffoldState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AnimationsScaffold&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Animations'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Ghost&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;floatingActionButton:&lt;/span&gt; &lt;span class="n"&gt;FloatingActionButton&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Start'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{},&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you analyze the final result that we want to obtain you can see that we have 2 animations.&lt;br&gt;
We need to change the position and the scale of our ghost, together.&lt;br&gt;
So we will need 2 animations and one animation controller to control them.&lt;br&gt;
Let's define and initialize them in our state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_AnimationsScaffoldState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AnimationsScaffold&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;TickerProviderStateMixin&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;late&lt;/span&gt; &lt;span class="n"&gt;AnimationController&lt;/span&gt; &lt;span class="n"&gt;_animationController&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;late&lt;/span&gt; &lt;span class="n"&gt;Animation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_positionAnimation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;late&lt;/span&gt; &lt;span class="n"&gt;Animation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_scaleAnimation&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalAnimationDuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;_animationController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AnimationController&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;vsync:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;duration:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;seconds:&lt;/span&gt; &lt;span class="n"&gt;totalAnimationDuration&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_positionAnimation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Tween&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nl"&gt;begin:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;end:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;animate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;CurvedAnimation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;parent:&lt;/span&gt; &lt;span class="n"&gt;_animationController&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;curve:&lt;/span&gt; &lt;span class="n"&gt;Interval&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
          &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
          &lt;span class="mf"&gt;0.35&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
          &lt;span class="nl"&gt;curve:&lt;/span&gt; &lt;span class="n"&gt;Curves&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_scaleAnimation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TweenSequence&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;(&lt;/span&gt;
      &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;TweenSequenceItem&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;tween:&lt;/span&gt; &lt;span class="n"&gt;Tween&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;begin:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;end:&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nl"&gt;weight:&lt;/span&gt; &lt;span class="mf"&gt;35.0&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;TweenSequenceItem&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;tween:&lt;/span&gt; &lt;span class="n"&gt;Tween&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;begin:&lt;/span&gt; &lt;span class="mf"&gt;1.25&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;end:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nl"&gt;weight:&lt;/span&gt; &lt;span class="mf"&gt;65.0&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="o"&gt;],&lt;/span&gt;
    &lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;animate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;CurvedAnimation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;parent:&lt;/span&gt; &lt;span class="n"&gt;_animationController&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;curve:&lt;/span&gt; &lt;span class="n"&gt;Curves&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_animationController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forward&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;dispose&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_animationController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see the &lt;code&gt;AnimationController&lt;/code&gt; object needs a async property with is an object that conforms to &lt;code&gt;TickerProvider&lt;/code&gt;, we can use our state object declaring the &lt;code&gt;TickerProviderStateMixin&lt;/code&gt; mixin.&lt;br&gt;
We've defined the position animation that goes from 0 to 1 in the first 35% part of the duration of the whole animation. &lt;br&gt;
Then we've defined the scale animation that goes from 0 to 1.25 in the first 35% part of the animation (using the weight parameter) and then it scales back from 1.25 to 1.0 in the rest 65%.&lt;br&gt;
Note that we need to dispose the animation controller in the dispose method of our widget.&lt;/p&gt;

&lt;p&gt;Now let's use those animations in our build method, using an &lt;code&gt;AnimatedBuilder&lt;/code&gt;. The &lt;code&gt;AnimatedBuilder&lt;/code&gt; takes the animation object as a parameter (we're using the animation controller) and a builder that will be called when the values of the animations are updated.&lt;br&gt;
It has also a &lt;code&gt;child&lt;/code&gt; parameter, that will be passed in the builder function, to prevent unnecessary builds, we're using the &lt;code&gt;Ghost&lt;/code&gt; widget here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="o"&gt;...&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;AnimatedBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;animation:&lt;/span&gt; &lt;span class="n"&gt;_animationController&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
              &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;initialPositionY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;cardSize&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
              &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;finalPositionY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                  &lt;span class="n"&gt;MediaQuery&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;cardSize&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Positioned&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;bottom:&lt;/span&gt; &lt;span class="n"&gt;initialPositionY&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                    &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;finalPositionY&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;initialPositionY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
                        &lt;span class="n"&gt;_positionAnimation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="nl"&gt;left:&lt;/span&gt; &lt;span class="n"&gt;MediaQuery&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;cardSize&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Transform&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scale&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;scale:&lt;/span&gt; &lt;span class="n"&gt;_scaleAnimation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;child&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                &lt;span class="o"&gt;),&lt;/span&gt;
              &lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;},&lt;/span&gt;
            &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Ghost&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt;
          &lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="o"&gt;],&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're done! 🎉&lt;br&gt;
We have our animation that starts when the Widget is created.&lt;br&gt;
The only little piece that's missing is to connect the floating action button to restart the animation. There's nothing as easy as this: you just need to call the reset function of the animation controller and then the forward function to start the animation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;      &lt;span class="nl"&gt;floatingActionButton:&lt;/span&gt; &lt;span class="n"&gt;FloatingActionButton&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Start'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;_animationController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reset&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
          &lt;span class="n"&gt;_animationController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forward&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want to check new Flutter tutorials every week? Look at &lt;a href="https://theotherdevs.com/mastering-flutter/"&gt;our site&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting to know Flutter: Pull to refresh with online data</title>
      <dc:creator>TheOtherDev/s</dc:creator>
      <pubDate>Thu, 09 Sep 2021 15:13:49 +0000</pubDate>
      <link>https://forem.com/theotherdevs/getting-to-know-flutter-pull-to-refresh-with-online-data-592i</link>
      <guid>https://forem.com/theotherdevs/getting-to-know-flutter-pull-to-refresh-with-online-data-592i</guid>
      <description>&lt;p&gt;Hi there! How you're doing? Everything's all right? Good. Today we 'll be doing a pretty easy task, a &lt;strong&gt;pull to refresh&lt;/strong&gt;, while using a &lt;strong&gt;CMS&lt;/strong&gt; in order to have online data and having more control on our example. Let's start!&lt;/p&gt;

&lt;h2&gt;
  
  
  What we'll need
&lt;/h2&gt;

&lt;p&gt;Our ingredients will be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A CMS account (we'll be using &lt;strong&gt;MBurger&lt;/strong&gt; as it is free to start)&lt;/li&gt;
&lt;li&gt;Android Studio&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flutter&lt;/strong&gt; basic knowledge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think it's a pretty easy recepie but it will also be very juicy!&lt;/p&gt;

&lt;h2&gt;
  
  
  MBurger configuration
&lt;/h2&gt;

&lt;p&gt;First we'll need to create a &lt;strong&gt;free account&lt;/strong&gt; on &lt;strong&gt;MBurger&lt;/strong&gt;, go to &lt;a href="https://mburger.cloud/login" rel="noopener noreferrer"&gt;this page&lt;/a&gt; to start. Then we can create a &lt;strong&gt;new project&lt;/strong&gt; or use one provided template. We'll start from scratch.&lt;/p&gt;

&lt;p&gt;Second we'll create a new &lt;strong&gt;block&lt;/strong&gt; for our app. A block contains a list of sections which will be composed by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Title&lt;/strong&gt; -&amp;gt; Text&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content&lt;/strong&gt; -&amp;gt; Text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll call it "&lt;em&gt;Articles&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy27a3u4r0c6xejdwsb6k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy27a3u4r0c6xejdwsb6k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next we'll create &lt;strong&gt;how our articles are composed&lt;/strong&gt;. As we stated before we want to just add a &lt;strong&gt;title&lt;/strong&gt; and a &lt;strong&gt;simple content&lt;/strong&gt;, so we'll create &lt;strong&gt;2 text elements&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xd1yqsgn8yoy36ih9y5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xd1yqsgn8yoy36ih9y5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As last thing we just need to create a &lt;strong&gt;section&lt;/strong&gt;, so an &lt;em&gt;article&lt;/em&gt;. We'll click on "&lt;strong&gt;Add Articles section&lt;/strong&gt;" and create a simple &lt;em&gt;Lorem Ipsum&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjp4u8k7vtesgd11rqurz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjp4u8k7vtesgd11rqurz.png" alt="Alt Text"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  MBurger SDK
&lt;/h2&gt;

&lt;p&gt;Before venturing into the depths of the &lt;strong&gt;MBurger SDK&lt;/strong&gt; we'll need to create a &lt;strong&gt;API Key&lt;/strong&gt;, which will be used to connect to our MBurger project in the app. Let's head to the &lt;strong&gt;settings&lt;/strong&gt; and create an &lt;em&gt;API Key&lt;/em&gt;. For our project we don't need anything more than read permissions, but we can also add write and delete permissions for our &lt;em&gt;API Key&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvu502pgpjqp53d24yf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzvu502pgpjqp53d24yf.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbw0mq2t7hwfhz9f5xt3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbw0mq2t7hwfhz9f5xt3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have done for now on &lt;strong&gt;MBurger&lt;/strong&gt; website. Let's head to &lt;a href="https://pub.dev/packages/mburger" rel="noopener noreferrer"&gt;MBurger pub.dev&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Let's add &lt;strong&gt;MBurger dependency&lt;/strong&gt; to a new Flutter project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nl"&gt;dependencies:&lt;/span&gt;
  &lt;span class="nl"&gt;flutter:&lt;/span&gt;
    &lt;span class="nl"&gt;sdk:&lt;/span&gt; &lt;span class="n"&gt;flutter&lt;/span&gt;

  &lt;span class="nl"&gt;cupertino_icons:&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nl"&gt;mburger:&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then on &lt;code&gt;initState&lt;/code&gt; method let's add our &lt;em&gt;API Key&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MBManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'MYAPIKEY'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let's create an &lt;strong&gt;easy list&lt;/strong&gt; and a &lt;code&gt;Future&lt;/code&gt; for &lt;strong&gt;getting&lt;/strong&gt; and &lt;strong&gt;parsing&lt;/strong&gt; our data. We should need the &lt;code&gt;block id&lt;/code&gt; of our articles block, which can be found directly in the MBurger dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MBManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;apiToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'MYAPIKEY'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;FutureBuilder&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;future:&lt;/span&gt; &lt;span class="n"&gt;getArticles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;builder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;itemCount:&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;itemBuilder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Article&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getArticles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;MBPaginatedResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MBSection&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;MBManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSections&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;blockId:&lt;/span&gt; &lt;span class="n"&gt;MYBLOCK_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;includeElements:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;items&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Article&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;Article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MBSection&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;elements&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;section&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;elements&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;elements&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'title'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;MBTextElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;MBTextElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pull to refresh implementation
&lt;/h2&gt;

&lt;p&gt;We have all set, let's add our &lt;strong&gt;pull to refresh&lt;/strong&gt;. Let's go to &lt;code&gt;pub.dev&lt;/code&gt; and let's implement &lt;a href="https://pub.dev/packages/pull_to_refresh" rel="noopener noreferrer"&gt;pull_to_refresh&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;First we'll need to create a &lt;code&gt;RefreshController&lt;/code&gt;, which will be attached to our &lt;strong&gt;Refresher&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;RefreshController&lt;/span&gt; &lt;span class="n"&gt;refreshControllerList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="n"&gt;RefreshController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;initialRefresh:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now wrap the &lt;code&gt;ListView&lt;/code&gt; around a &lt;code&gt;SmartRefresher&lt;/code&gt;, which is the &lt;strong&gt;main widget&lt;/strong&gt; controlling the pull-to-refresh behavior. &lt;code&gt;SmartRefresher&lt;/code&gt; has a lot of customization options, you can check more on the &lt;a href="https://pub.dev/packages/pull_to_refresh" rel="noopener noreferrer"&gt;official page on pub.dev&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;SmartRefresher&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;controller:&lt;/span&gt; &lt;span class="n"&gt;refreshControllerList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;enablePullDown:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;onRefresh:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_onRefresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;itemCount:&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nl"&gt;itemBuilder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="n"&gt;Article&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;snapshot&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                      &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;article&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="p"&gt;],&lt;/span&gt;
                  &lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;onRefresh&lt;/code&gt; parameter should point to an &lt;code&gt;async&lt;/code&gt; function which should call again our future:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_onRefresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;getArticles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;refreshControllerList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refreshCompleted&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;refreshControllerList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;refreshFailed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the app is open then we'll need to add a new section to our &lt;strong&gt;MBurger project&lt;/strong&gt;. Then with a swipe the list will be refreshed and we'll see the new item on our list. All done!!&lt;/p&gt;

&lt;p&gt;Want to check more awesome tutorials? &lt;a href="https://theotherdevs.com/getting-to-know-flutter/" rel="noopener noreferrer"&gt;Click here!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dart</category>
      <category>flutter</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
