<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Rushil Makkar]]></title><description><![CDATA[Hey, I am a Flutter and Golang developer. I am currently working as Head of Development with a US-based EdTech startup. I have an engineering degree in Electron]]></description><link>https://devrush.tech</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1667068787900/QfApkRKVJ.png</url><title>Rushil Makkar</title><link>https://devrush.tech</link></image><generator>RSS for Node</generator><lastBuildDate>Sun, 12 Apr 2026 17:14:30 GMT</lastBuildDate><atom:link href="https://devrush.tech/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Navigating the Landscape of Flutter State Management: Choosing the Right Approach for Every Scenario]]></title><description><![CDATA[Introduction
In the dynamic world of Flutter development, the art of selecting the most suitable state management solution is a critical skill for every developer. Flutter provides a plethora of options, each tailored to specific scenarios. This comp...]]></description><link>https://devrush.tech/navigating-the-landscape-of-flutter-state-management-choosing-the-right-approach-for-every-scenario</link><guid isPermaLink="true">https://devrush.tech/navigating-the-landscape-of-flutter-state-management-choosing-the-right-approach-for-every-scenario</guid><category><![CDATA[State Management ]]></category><category><![CDATA[Flutter]]></category><category><![CDATA[BLoC]]></category><category><![CDATA[Provider]]></category><category><![CDATA[Riverpod]]></category><dc:creator><![CDATA[Rushil Makkar]]></dc:creator><pubDate>Tue, 12 Dec 2023 22:59:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/cckf4TsHAuw/upload/5e70d2cb0a5202f7e819be4f5d624434.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>In the dynamic world of Flutter development, the art of selecting the most suitable state management solution is a critical skill for every developer. Flutter provides a plethora of options, each tailored to specific scenarios. This comprehensive guide aims to empower developers with the knowledge needed to make strategic decisions, exploring the strengths and ideal use cases for different state management solutions.</p>
<h2 id="heading-1-statefulwidget-and-inheritedwidget-embracing-simplicity"><strong>1. StatefulWidget and InheritedWidget: Embracing Simplicity</strong></h2>
<p><strong>When to Use:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Small, isolated components or widgets with minimal state needs.</p>
</li>
<li><p><strong>Advantages:</strong> Lightweight, minimal boilerplate, straightforward implementation.</p>
</li>
<li><p><strong>Considerations:</strong> Limited to local scope; may not scale well for larger applications.</p>
</li>
</ul>
<p>For scenarios where simplicity is key, <code>StatefulWidget</code> and <code>InheritedWidget</code> provide a straightforward solution. These built-in tools are perfect for managing state within smaller components without introducing unnecessary complexity.</p>
<h2 id="heading-2-bloc-architecture-tackling-complexity-with-modularity"><strong>2. BLoC Architecture: Tackling Complexity with Modularity</strong></h2>
<p><strong>When to Use:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Medium to large-scale applications with intricate state requirements.</p>
</li>
<li><p><strong>Advantages:</strong> Clear separation of concerns, scalability, testability.</p>
</li>
<li><p><strong>Considerations:</strong> Initial setup may seem verbose; benefits become more apparent with application complexity.</p>
</li>
</ul>
<p>BLoC architecture shines in projects where complexity demands a structured approach. Its clear separation of business logic and presentation logic makes it an ideal choice for applications that need to scale without compromising modularity.</p>
<h2 id="heading-3-provider-package-a-lightweight-elegance"><strong>3. Provider Package: A Lightweight Elegance</strong></h2>
<p><strong>When to Use:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Projects prioritizing simplicity, flexibility, and reduced boilerplate.</p>
</li>
<li><p><strong>Advantages:</strong> Minimal setup, ease of use, flexibility.</p>
</li>
<li><p><strong>Considerations:</strong> May not be the best fit for extremely large applications with intricate state interactions.</p>
</li>
</ul>
<p>For those who appreciate minimalism and elegance, the Provider package offers a lightweight solution. It reduces boilerplate code while maintaining clarity, making it an excellent choice for projects where simplicity is a priority.</p>
<h2 id="heading-4-riverpod-staying-ahead-with-evolving-solutions"><strong>4. Riverpod: Staying Ahead with Evolving Solutions</strong></h2>
<p><strong>When to Use:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Projects aiming to stay current with the latest advancements.</p>
</li>
<li><p><strong>Advantages:</strong> Improved syntax, better performance, evolving ecosystem.</p>
</li>
<li><p><strong>Considerations:</strong> Still relatively new; may have a learning curve for developers accustomed to Provider.</p>
</li>
</ul>
<p>As an evolution of Provider, Riverpod introduces improvements in syntax and performance. It's an excellent choice for projects that value staying ahead of the curve and adopting the latest features and optimizations.</p>
<h2 id="heading-strategic-decision-making-considering-skillset-and-project-roadmap"><strong>Strategic Decision-Making: Considering Skillset and Project Roadmap</strong></h2>
<p><strong>When to Prioritize Team Skillset:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Leveraging the strengths and preferences of your team.</p>
</li>
<li><p><strong>Advantages:</strong> Boosts productivity, reduces learning curves.</p>
</li>
<li><p><strong>Considerations:</strong> Balance with project requirements; encourage continuous skill development.</p>
</li>
</ul>
<p>Consider the team's proficiency when making decisions. If developers are skilled in reactive paradigms, solutions like Provider or Riverpod might align well with their expertise.</p>
<p><strong>When to Anticipate Long-Term Maintainability:</strong></p>
<ul>
<li><p><strong>Scenario:</strong> Planning for the future, considering scalability.</p>
</li>
<li><p><strong>Advantages:</strong> Reduces technical debt, accommodates future features.</p>
</li>
<li><p><strong>Considerations:</strong> Balancing short-term development speed with long-term maintainability.</p>
</li>
</ul>
<p>Evaluate potential challenges and select solutions that align with the project's long-term roadmap. Consider factors such as scalability and ease of accommodating future features.</p>
<h2 id="heading-conclusion-empowering-developers-for-informed-choices"><strong>Conclusion: Empowering Developers for Informed Choices</strong></h2>
<p>Choosing the right state management solution in Flutter is a skill that every developer should hone. This guide provides a roadmap for understanding the strengths of each solution and the scenarios in which they shine. By considering simplicity, modularity, and staying current with evolving solutions, developers can make informed choices that strike the right balance for their specific projects. This strategic approach ensures that Flutter applications are not only efficient in the short term but also poised for long-term success in the ever-evolving world of app development.</p>
]]></content:encoded></item><item><title><![CDATA[Unveiling Real-Time Performance Monitoring in Flutter: Strategies for Optimal App Health]]></title><description><![CDATA[Introduction:
Creating a Flutter app that delights users requires not only stunning visuals but also optimal performance. Real-time performance monitoring is a critical aspect of ensuring your app runs smoothly across various devices and scenarios. I...]]></description><link>https://devrush.tech/unveiling-real-time-performance-monitoring-in-flutter-strategies-for-optimal-app-health</link><guid isPermaLink="true">https://devrush.tech/unveiling-real-time-performance-monitoring-in-flutter-strategies-for-optimal-app-health</guid><category><![CDATA[Flutter]]></category><category><![CDATA[Performance Optimization]]></category><category><![CDATA[monitoring tool]]></category><category><![CDATA[Firebase]]></category><category><![CDATA[devtools]]></category><dc:creator><![CDATA[Rushil Makkar]]></dc:creator><pubDate>Tue, 12 Dec 2023 22:41:33 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction:</h2>
<p>Creating a Flutter app that delights users requires not only stunning visuals but also optimal performance. Real-time performance monitoring is a critical aspect of ensuring your app runs smoothly across various devices and scenarios. In this comprehensive article, we'll delve into the significance of real-time performance monitoring in Flutter and explore strategies to enhance app health.</p>
<h2 id="heading-why-real-time-performance-monitoring-matters"><strong>Why Real-Time Performance Monitoring Matters:</strong></h2>
<h3 id="heading-1-user-experience-optimization">1. <strong>User Experience Optimization:</strong></h3>
<p>Real-time performance monitoring provides insights into how users experience your app. By tracking metrics like frame rates, response times, and resource utilization, developers can identify and address performance issues that directly impact the user experience.</p>
<h3 id="heading-2-proactive-issue-detection">2. <strong>Proactive Issue Detection:</strong></h3>
<p>Detecting performance issues in real-time allows developers to be proactive in addressing potential bottlenecks or slowdowns. Early detection means faster resolution, resulting in a more responsive and stable app.</p>
<h3 id="heading-3-device-compatibility-testing">3. <strong>Device Compatibility Testing:</strong></h3>
<p>Different devices have varying capabilities, and real-time monitoring helps assess how your app performs across a spectrum of devices. This information is invaluable for ensuring a consistent experience for users, regardless of the device they're using.</p>
<h2 id="heading-implementing-real-time-performance-monitoring-in-flutter"><strong>Implementing Real-Time Performance Monitoring in Flutter:</strong></h2>
<h3 id="heading-1-firebase-performance-monitoring">1. <strong>Firebase Performance Monitoring:</strong></h3>
<p>Firebase Performance Monitoring is a robust tool for monitoring your Flutter app's performance in real-time. Integrated seamlessly with Flutter, it provides detailed insights into issues like slow network requests, slow rendering, and more.</p>
<h4 id="heading-setting-up-firebase-performance-monitoring">Setting up Firebase Performance Monitoring:</h4>
<ul>
<li><p>Add the Firebase SDK to your Flutter project.</p>
</li>
<li><p>Initialize Firebase in your app.</p>
</li>
</ul>
<pre><code class="lang-dart"><span class="hljs-keyword">void</span> main() {
  WidgetsFlutterBinding.ensureInitialized();
  <span class="hljs-keyword">await</span> Firebase.initializeApp();
  runApp(MyApp());
}
</code></pre>
<ul>
<li>Enable Performance Monitoring in the Firebase Console.</li>
</ul>
<h3 id="heading-2-custom-metrics-and-analytics">2. <strong>Custom Metrics and Analytics:</strong></h3>
<p>Supplement standard metrics with custom performance indicators tailored to your app's specific needs. Use analytics tools like <code>flutter_analytics</code> to track custom events and performance-related data.</p>
<pre><code class="lang-dart">Analytics.logEvent(<span class="hljs-string">'custom_performance_metric'</span>, parameters: {
  <span class="hljs-string">'time_taken'</span>: <span class="hljs-string">'300ms'</span>,
  <span class="hljs-string">'action'</span>: <span class="hljs-string">'button_click'</span>,
});
</code></pre>
<h3 id="heading-3-integration-with-devtools">3. <strong>Integration with DevTools:</strong></h3>
<p>Leverage Flutter DevTools for in-depth performance analysis during development. DevTools offers a range of features, including a timeline view, memory profiler, and CPU profiler, allowing you to identify and resolve performance issues in real-time.</p>
<h4 id="heading-running-devtools">Running DevTools:</h4>
<ul>
<li>Run your app with DevTools:</li>
</ul>
<pre><code class="lang-bash">flutter run --enable-vmservice
</code></pre>
<ul>
<li>Open DevTools in your browser at <a target="_blank" href="http://localhost:9100"><code>http://localhost:9100</code></a>.</li>
</ul>
<h3 id="heading-4-continuous-integration-ci-integration">4. <strong>Continuous Integration (CI) Integration:</strong></h3>
<p>Integrate real-time performance monitoring into your CI/CD pipeline. Tools like Jenkins, Travis CI, or GitHub Actions can be configured to run performance tests automatically on each code push, ensuring that performance issues are caught early in the development process.</p>
<h2 id="heading-best-practices-for-real-time-performance-monitoring"><strong>Best Practices for Real-Time Performance Monitoring:</strong></h2>
<h3 id="heading-1-set-performance-goals">1. <strong>Set Performance Goals:</strong></h3>
<p>Define specific performance goals for your app, such as maximum response times or minimum frame rates. Regularly measure and compare your app's performance against these goals.</p>
<h3 id="heading-2-user-centric-monitoring">2. <strong>User-centric Monitoring:</strong></h3>
<p>Focus on metrics that directly impact users, such as screen load times, touch responsiveness, and animation smoothness. Prioritize improvements based on their impact on user experience.</p>
<h3 id="heading-3-periodic-audits">3. <strong>Periodic Audits:</strong></h3>
<p>Perform regular audits of your app's performance. Set up periodic checks to ensure that your app continues to meet performance standards as it evolves.</p>
<h2 id="heading-conclusion"><strong>Conclusion:</strong></h2>
<p>Real-time performance monitoring is not just a reactive measure but a proactive strategy for creating high-performing Flutter applications. By integrating tools like Firebase Performance Monitoring, custom analytics, and Flutter DevTools into your development process, you can gain valuable insights and ensure that your app delivers a consistently optimal user experience. Embrace a culture of continuous improvement, set performance goals, and leverage real-time monitoring to keep your Flutter app running at its best.</p>
]]></content:encoded></item><item><title><![CDATA[Mastering Flutter Performance: Advanced Strategies for Size, Rendering, and Beyond]]></title><description><![CDATA[Introduction:
Flutter, the cross-platform UI toolkit by Google, empowers developers to create visually stunning and performant applications. Achieving peak performance in a Flutter app requires a deep understanding of advanced optimization techniques...]]></description><link>https://devrush.tech/mastering-flutter-performance-advanced-strategies-for-size-rendering-and-beyond</link><guid isPermaLink="true">https://devrush.tech/mastering-flutter-performance-advanced-strategies-for-size-rendering-and-beyond</guid><category><![CDATA[Flutter]]></category><category><![CDATA[Performance Optimization]]></category><category><![CDATA[Mobile Development]]></category><category><![CDATA[coding]]></category><dc:creator><![CDATA[Rushil Makkar]]></dc:creator><pubDate>Tue, 12 Dec 2023 22:32:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/s8HyIEe7lF0/upload/2ab7408a7fab5a2273b52c1c3880d5cd.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction:</strong></h2>
<p>Flutter, the cross-platform UI toolkit by Google, empowers developers to create visually stunning and performant applications. Achieving peak performance in a Flutter app requires a deep understanding of advanced optimization techniques. In this expert-level article, we will explore cutting-edge strategies for size reduction, rendering speed enhancement, and delve into sophisticated performance considerations.</p>
<h3 id="heading-1-dynamic-code-loading-and-modularization">1. <strong>Dynamic Code Loading and Modularization:</strong></h3>
<p>Taking code splitting to the next level involves dynamic code loading and modularization. Explore techniques such as on-the-fly module loading using <code>flutter_dynamic_import</code> to load modules based on runtime conditions, reducing the initial bundle size.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Example of dynamic code loading in Flutter</span>
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_dynamic_import/flutter_dynamic_import.dart'</span>;

<span class="hljs-keyword">void</span> main() <span class="hljs-keyword">async</span> {
  <span class="hljs-keyword">final</span> myModule = <span class="hljs-keyword">await</span> dynamicImport(<span class="hljs-string">"my_module.dart"</span>);
  runApp(myModule.MyApp());
}
</code></pre>
<h3 id="heading-2-optimizing-network-requests">2. <strong>Optimizing Network Requests:</strong></h3>
<p>Implement advanced caching mechanisms for network requests to minimize data transfer. Utilize libraries like <code>dio</code> for fine-grained control over HTTP requests, and explore GraphQL for more efficient data fetching, reducing over-fetching and under-fetching.</p>
<pre><code class="lang-dart"><span class="hljs-comment">// Example of Dio caching in Flutter</span>
<span class="hljs-keyword">final</span> dio = Dio();

Response response = <span class="hljs-keyword">await</span> dio.<span class="hljs-keyword">get</span>(
  <span class="hljs-string">'https://api.example.com/data'</span>,
  options: Options(
    headers: {<span class="hljs-string">'Cache-Control'</span>: <span class="hljs-string">'max-age=3600'</span>},
  ),
);
</code></pre>
<h3 id="heading-3-custom-compilation-with-flutter-tree-shaking">3. <strong>Custom Compilation with Flutter Tree Shaking:</strong></h3>
<p>Customize the tree-shaking process to eliminate even more unused code. Explore tools like <code>dart2native</code> for AOT compilation to native machine code, resulting in smaller executables and improved runtime performance.</p>
<pre><code class="lang-bash">dart2native my_app.dart -o my_app
</code></pre>
<h3 id="heading-4-advanced-state-management-for-efficiency">4. <strong>Advanced State Management for Efficiency:</strong></h3>
<p>Move beyond basic state management and explore advanced techniques. Utilize tools like <code>riverpod</code> or <code>get_it</code> for efficient dependency injection and state management. Minimize unnecessary widget rebuilds by employing state management solutions that offer granular control over updates.</p>
<h3 id="heading-5-hardware-accelerated-graphics">5. <strong>Hardware-Accelerated Graphics:</strong></h3>
<p>Harness the power of hardware acceleration for graphics-intensive applications. Explore the use of the <code>flutter_svg</code> package for scalable vector graphics and leverage Flutter's <code>CustomPainter</code> for low-level graphics rendering, enabling the creation of visually rich and performant UIs.</p>
<h3 id="heading-6-compiler-profiling-and-optimization">6. <strong>Compiler Profiling and Optimization:</strong></h3>
<p>Delve into compiler profiling tools like <code>dart2js</code> and <code>dart2native</code>. Profile your Dart code to identify bottlenecks and leverage compiler optimizations. Experiment with flags such as <code>--release</code> and <code>--fast-startup</code> for improved performance in production builds.</p>
<h3 id="heading-7-real-time-performance-monitoring">7. <strong>Real-Time Performance Monitoring:</strong></h3>
<p>Implement real-time performance monitoring using tools like Firebase Performance Monitoring. Gain insights into application performance on real devices and identify areas for improvement, ensuring a consistently smooth user experience.</p>
<h3 id="heading-conclusion">Conclusion:</h3>
<p>Mastering Flutter performance at an expert level requires a blend of advanced techniques, strategic thinking, and a deep understanding of the underlying mechanisms. By incorporating dynamic code loading, optimizing network requests, customizing compilation, employing advanced state management, leveraging hardware-accelerated graphics, and profiling for optimization, developers can elevate their Flutter applications to peak performance. Stay at the forefront of Flutter advancements, continually experiment with new tools, and refine your approach to deliver unparalleled performance in your Flutter projects.</p>
]]></content:encoded></item><item><title><![CDATA[Interactive Tutorial of App for Users | Flutter]]></title><description><![CDATA[What I meant by interactive demo/tutorial, and it's need
While finishing the app for one of my clients, a problem we encountered was with onboarding the new users and guiding them through all the available features, and giving them a tutorial on thos...]]></description><link>https://devrush.tech/demo-guide-of-app-for-users</link><guid isPermaLink="true">https://devrush.tech/demo-guide-of-app-for-users</guid><category><![CDATA[Flutter]]></category><category><![CDATA[Flutter Examples]]></category><category><![CDATA[Tutorial]]></category><category><![CDATA[user experience]]></category><category><![CDATA[user onboarding]]></category><dc:creator><![CDATA[Rushil Makkar]]></dc:creator><pubDate>Sat, 29 Oct 2022 08:14:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/HpWwEURimK8/upload/v1667068397445/tnQfuSiPh.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-i-meant-by-interactive-demotutorial-and-its-need">What I meant by interactive demo/tutorial, and it's need</h2>
<p>While finishing the app for one of my clients, a problem we encountered was with onboarding the new users and guiding them through all the available features, and giving them a tutorial on those features at the same time. I think creating a demo guide for new users is a crucial part of customer onboarding as it not only introduces users to your app but also gives them insight as to how to use it.</p>
<p>There are two cases where I have found this useful-</p>
<ul>
<li><p>Onboarding new users</p>
</li>
<li><p>Introducing new features/changes for old users</p>
</li>
</ul>
<h2 id="heading-what-we-are-going-to-achieve">What we are going to achieve</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667029626501/8aPWIhDMr.gif" alt="coachgif.gif" /></p>
<p>In this article, we are going to achieve the same with the help of a flutter package - <a target="_blank" href="https://pub.dev/packages/tutorial_coach_mark">Tutorial Coach Mark</a></p>
<h2 id="heading-implementation">Implementation</h2>
<p>I have created a demo guide for the flutter demo counter app that we get on creating a new project.</p>
<p>The widget we want to focus on or highlight during the demo is called a <strong>target</strong>. Each target has to be associated with a global key that will be used to find that widget.</p>
<pre><code class="lang-plaintext">  late TutorialCoachMark tutorialCoachMark;
  GlobalKey counterIconKey = GlobalKey();
  GlobalKey progressKey = GlobalKey();
</code></pre>
<p>Let's associate the global keys with the widgets that we want to highlight -</p>
<pre><code class="lang-plaintext">//progress text
Text(
        '$_counter',
         key: progressKey,
         style: Theme.of(context).textTheme.headline4,
        )

//action button to increase the progress counter
floatingActionButton: FloatingActionButton(
        key: counterIconKey,
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      )
</code></pre>
<p>Now let's create a list of targets that we want to focus on -</p>
<p>We will add each target using TargetFocus class. TargetFocus contains an <em>identify</em> text, <em>keyTarget</em> and the <em>contents</em> to display on the screen while highlighting the target.</p>
<p>In <em>keyTarget</em>, use the global key associated with the widget that you want to highlight. In <em>contents</em>, use builder method of TargetContent class to display flutter widgets on screen at the time that particular widget from app is highlighted. So, in <em>contents</em>, you will use widgets to guide the user about the app.</p>
<p>This function will return a list of all the targets.</p>
<pre><code class="lang-plaintext">List&lt;TargetFocus&gt; _createTargets() {
    List&lt;TargetFocus&gt; targets = [];
    targets.add(
      TargetFocus(
        identify: "counterIcon",
        keyTarget: counterIconKey,
        alignSkip: Alignment.topRight,
        contents: [
          TargetContent(
            align: ContentAlign.top,
            builder: (context, controller) {
              return Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: const &lt;Widget&gt;[
                  Text(
                    "Press this button to increase the counter by one",
                    style: TextStyle(
                      color: Colors.white,
                    ),
                  ),
                ],
              );
            },
          ),
        ],
      ),
    );
    targets.add(
      TargetFocus(
        identify: "progressText",
        keyTarget: progressKey,
        alignSkip: Alignment.topRight,
        contents: [
          TargetContent(
            align: ContentAlign.top,
            builder: (context, controller) {
              return Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: const &lt;Widget&gt;[
                  Text(
                    "You can check the current counter progress here",
                    style: TextStyle(
                      color: Colors.white,
                    ),
                  ),
                  Text(
                    "Congrats! This is the end of the tutorial. Try pressing the counter icon.",
                    style: TextStyle(
                      color: Colors.white,
                    ),
                  ),
                ],
              );
            },
          ),
        ],
      ),
    );
    return targets;
  }
</code></pre>
<p>Now let's create a function to create the tutorial and tie everything together. Here we will define the <em>tutorialCoachMark</em> variable that we declared earlier and this will define our entire demo. Use the <em>_createTargets</em> method that we defined earlier to get the list of <em>TargetFocus</em> and define the basic properties such as shadow color, opacity and what happens on skipping or finishing the demo.</p>
<pre><code class="lang-plaintext">void createTutorial() {
    tutorialCoachMark = TutorialCoachMark(
      targets: _createTargets(),
      colorShadow: Colors.red,
      textSkip: "SKIP",
      paddingFocus: 10,
      opacityShadow: 0.8,
      onFinish: () {
        print("finish");
      },
      onClickTarget: (target) {
        print('onClickTarget: $target');
      },
      onClickTargetWithTapPosition: (target, tapDetails) {
        print("target: $target");
        print(
            "clicked at position local: ${tapDetails.localPosition} - global: ${tapDetails.globalPosition}");
      },
      onClickOverlay: (target) {
        print('onClickOverlay: $target');
      },
      onSkip: () {
        print("skip");
      },
    );
  }
</code></pre>
<p>Once this setup is done, call this create tutorial function in <em>initState</em> to define the demo and then display it.</p>
<pre><code class="lang-plaintext">  @override
  void initState() {
    createTutorial();
    WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
      tutorialCoachMark.show(context: context);
    });
    super.initState();
  }
</code></pre>
<h2 id="heading-note">Note</h2>
<p>You can use <a target="_blank" href="https://pub.dev/packages/shared_preferences">shared_preferences</a> package or any other condition to make sure that this demo guide is not displayed every time you reload the app.</p>
<p>This is it for this article :) Subscribe to the newsletter for more.</p>
]]></content:encoded></item></channel></rss>