<?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>DEV Community: Jenish MS</title>
    <description>The latest articles on DEV Community by Jenish MS (@jenishms).</description>
    <link>https://dev.to/jenishms</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%2F760727%2F15560646-7a41-41b6-be85-d22ab2508ab3.jpeg</url>
      <title>DEV Community: Jenish MS</title>
      <link>https://dev.to/jenishms</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jenishms"/>
    <language>en</language>
    <item>
      <title>Top Mobile Apps Developed with the Flutter Framework</title>
      <dc:creator>Jenish MS</dc:creator>
      <pubDate>Fri, 03 May 2024 08:51:19 +0000</pubDate>
      <link>https://dev.to/jenishms/top-mobile-apps-developed-with-the-flutter-framework-3k2b</link>
      <guid>https://dev.to/jenishms/top-mobile-apps-developed-with-the-flutter-framework-3k2b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction:&lt;/strong&gt;&lt;br&gt;
Flutter, Google’s UI toolkit, is reshaping mobile app development with its ability to create cross-platform applications seamlessly. This article explores how Flutter’s single codebase empowers developers to craft top-notch applications for mobile, web, and desktop. Dive into the innovative world of Flutter, where cutting-edge solutions and versatile performance redefine the landscape.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.google.android.apps.nbu.paisa.user"&gt;Google Pay&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
With 100 million users globally, “Google Pay” faced scalability challenges managing 1.7 million lines of code between Android and iOS apps. Expanding to new regions with unique features proved unsustainable, necessitating a shift to Flutter, a cross-platform framework. Despite challenges like retraining teams and undergoing security audits, a small group demonstrated Flutter’s potential by building a vertical slice of the app. Impressed with instant feedback and quality widgets, Google Pay migrated to Flutter, successfully launching in Singapore. Encouraged, they rapidly expanded the team, rewriting 300 features for a beta launch in India and the US. Google Pay 3.0, built on Flutter, positions the app for efficient scaling across iOS and Android, with a major US relaunch and global expansion planned for 2021.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=de.bmw.connected.mobile20.na"&gt;BMW&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
In 2018, BMW faced growing discrepancies between their iOS and Android vehicle companion apps. Striving for unified functionality across platforms, regions, and brands, they adopted Flutter in October 2019. The move allowed for a flexible organizational structure and simultaneous releases worldwide. The “Mobile 2.0 Platform” enabled automated builds, tests, and deployments for diverse app variants, resulting in over 10,000 versions. Launched in July 2020, the “My BMW” App established a seamless interface in 47 countries. Flutter eliminated feature disparities, offering a consistent experience for all users and accelerating development. The shift to Flutter not only enhanced user feedback but also streamlined operations, allowing BMW to maintain speed, consistency, and user satisfaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.alibaba.intl.android.apps.poseidon"&gt;Alibaba&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Alibaba’s Xianyu, a platform that maximises the value of idle resources, has over 50 million users who are using Flutter, a mobile app SDK by Google. Flutter allows developers to build apps for iOS and Android using a single codebase, which makes the maintenance of apps easier and faster. The platform aims to create a new lifestyle for the younger generation, where vendors can sell their products and customers can buy them with ease. Xianyu incorporated Flutter’s user experience, which includes high FPS and smooth UI, and the expressive UI widgets allowed them to make sleek UI. The ItemDetail page, which is the most important and frequently visited section, is run through a single codebase on Android and iOS using Flutter. The ItemPost page, a cornerstone of Xianyu’s app, was also developed through Flutter. The platform is excited to build many more features using Flutter to move Alibaba’s Xianyu forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.dream11.com/"&gt;Dream11&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
“Dream11”, India’s largest sports game with around 50 million registered users, has used Flutter to create a new app for predicting the outcomes of cricket games. The app, called Predictor, was developed for Android first and was up and running within weeks. The Dart programming language used by Flutter was found to be intuitive and easy to learn, even for developers from different backgrounds. Dream11 plans to use Flutter for future projects and promote competition between users of its platform by encouraging them to create their own teams. The app also features hot reloading and sweet debugging, allowing developers to see the outcome of changes they make in real-time. Flutter’s ability to handle every story value impressed Dream11, and the company plans to use the framework for many future projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.nu.production"&gt;Nubank&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
“Nubank”, the largest independent digital bank outside of Asia, serves over 48 million users, providing a user-friendly financial management platform. Faced with the challenge of rapid growth and the need for quick product development, Nubank adopted Flutter as its cross-platform solution. Flutter’s streamlined UI and ease of onboarding enabled backend developers to contribute to the mobile front-end, eliminating the need for specialised teams. This shift allowed Nubank to accelerate feature releases and maintain quality. Flutter’s simplicity facilitated a smooth transition for engineers to become full-stack developers, enhancing productivity and overall job satisfaction. The platform’s efficiency has empowered Nubank to scale effectively while optimising development processes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.tencent.ig"&gt;PUBG Mobile&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
“PUBG MOBILE”, developed by Lightspeed Studios and Krafton, has achieved 1 billion players globally, with 50 million daily active players. Seeking to enhance in-game community experiences, they opted for Flutter, a cross-platform framework, for efficient coverage on both Android and iOS. Flutter’s advantages included high performance, easy integration, and an 80% reduction in front-end development effort by allowing code to be written once. This single codebase prevented inconsistencies between platforms, ensuring a seamless user experience. The in-game community module, a Flutter implementation, has thrived, with around 10 million monthly users sharing gaming experiences. The PUBG MOBILE Dev team plans to further optimise the user experience and leverage Flutter for future scenarios, acknowledging its role in saving developer time and reducing costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.ebay.motorsapp"&gt;eBay Motors&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
In response to the need for a specialized app for auto enthusiasts, “eBay Motors” turned to Flutter in 2018 to develop a cross-platform solution for Android and iOS within a tight deadline. Flutter’s capabilities exceeded expectations, offering a faster and more enjoyable development experience compared to native tools. The team embraced Flutter’s out-of-the-box testing support, achieving 100% code coverage, and benefited from substantial code sharing for UI, business logic, and more. Unifying Android and iOS teams, they launched a beta within three months and a full production app shortly after. Developers overwhelmingly preferred Flutter, citing it as twice as fast, enabling weekly updates and simultaneous feature additions. The eBay Motors team attests that Flutter not only improved their workflow but fundamentally transformed their approach, fostering productivity, happiness, and excitement about their work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.hamilton.app"&gt;Hamilton&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Posse, a New York-based development firm, collaborated with the team behind the musical “Hamilton” to create a Flutter app expanding the show’s brand. Launched on the App Store and Google Play three months after the first code line, the app offers fans a chance at $10 tickets through a daily lottery, merchandise purchases, Ham Cam selfies, and daily news updates. Flutter’s pixel-perfect results, high performance, and the hot reload feature impressed the developers, allowing swift feature development. The active and supportive Flutter community contributed to the app’s success, surpassing expectations. The team made last-minute changes and introduced a new feature the day before launch. Flutter’s efficiency continues to support feature updates, including a recent trivia game, keeping pace with the show’s growth.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.ebay.kijiji.ca"&gt;Toyota&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
Toyota, known for meticulous attention to the driving experience, embraced Flutter to enhance in-vehicle infotainment systems. Leveraging Flutter’s Embedder API, Toyota developed Linux-powered infotainment, utilising cross-compilation and embedding to seamlessly integrate the Flutter engine. Dart and Flutter SDK facilitated the creation of in-house tools, streamlining the development process with declarative UI and code-as-configuration principles. The collaboration with Flutter’s open-source community proved pivotal, contributing to Toyota’s success in achieving their goals. With plans for a new infotainment system in future Toyota vehicles, Flutter’s architecture and vibrant ecosystem have played a crucial role in optimizing the user experience for drivers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.ebay.kijiji.ca"&gt;Kijiji&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
“Kijiji”, with nearly 11 million monthly users, faced codebase challenges in their native apps, leading them to rebuild with Flutter. The switch eradicated technical debt, facilitated cross-platform feature parity, and streamlined development. Flutter’s framework eliminated the need for overloaded custom views, ensuring code reusability without compromising stability. The migration to Flutter drastically reduced development time, enabling the recreation of core features in just 9 months, compared to the original 2–3 years per platform. Feature release time halved, fostering innovation and faster market response. Impressively, Kijiji hired 12 experienced Flutter developers within 6 months, enhancing their competitive edge. The codebase reduction from over 2.5M to approximately 900k lines with 100% coverage simplified maintenance and mitigated future technical debt. The new Flutter app was successfully rolled out to users on March 7/23.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.google.android.apps.classroom"&gt;Google Classroom&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
“Google Classroom” serves as a pivotal tool in education, enabling teachers and students to collaborate, share resources, and manage assignments efficiently. Whether developed with Flutter, the app exemplifies Google’s commitment to providing a user-friendly and accessible platform for online learning. Its intuitive interface, real-time collaboration features, and integration with other Google services contribute to its widespread adoption in educational settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.bytedance.com/en/"&gt;ByteDance&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
In 2019, ByteDance sought a more efficient toolkit for their app development needs. Adopting Flutter proved transformative, enabling them to create apps across multiple platforms with a single development effort. Flutter’s unique rendering engine ensured consistent performance on Android, iOS, and the web. ByteDance customised Flutter’s open-source framework, contributing optimisations that enhanced the platform for all users. Their first real-world application was an education app for teaching Chinese character writing, utilising Flutter’s stroke-tracking feature. This innovative approach, employing SVG paths to represent strokes, now supports over 9,000 Chinese characters and has proven successful across various platforms. ByteDance’s collaboration with Flutter exemplifies the framework’s adaptability and its potential for diverse, large-scale app development needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=de.lotum.whatsinthefoto.us"&gt;4 Pics 1 Word&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
After eight successful years with over 450 million downloads of their flagship game “4 Pics 1 Word,” Lotum faced a decline in user numbers and sought a refresh. Opting for Flutter, they completely rewrote the game as a cross-platform app. Flutter’s unique rendering engine, Skia, provided a consistent layout, look, and feel, addressing previous feature parity concerns. Contrary to expectations of a temporary drop in user engagement, the Flutter version not only maintained user numbers but also showed improved stability, boasting a 99.9% crash-free rate. Seamless integration with Google AdMob was a highlight, given Lotum’s heavy reliance on ads for revenue. The successful transition has left the development team excited about Flutter, with plans to continue using it for future app development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.irobot.home"&gt;iRobot&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
“iRobot” Education, renowned for Roomba® Robot Vacuums, expanded its educational reach with the iRobot Coding App. Initially available only on iOS, the goal was to make STEM education more accessible by developing Android and web versions. Opting for Flutter, the team swiftly wrote production code and released a multiplatform app in weeks. Despite most team members being new to Flutter and Dart, the result was a high-quality, cross-platform app on Android, iOS, and the web. Since the launch, the iRobot Coding App has seen remarkable growth, reaching 170 countries and quadrupling monthly active users. Easier maintenance enables a focus on new features, including a 3D simulator, showcasing Flutter’s impact on educational outreach. The iRobot Education engineering team now boasts two full-time Flutter developers for ongoing development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;br&gt;
Flutter has revolutionised mobile app development, showcasing its prowess in creating visually appealing, responsive, and high-performance cross-platform experiences. As it gains widespread adoption, the future holds promise for developers and businesses seeking efficient solutions. The success stories highlighted here inspire aspiring developers and tech enthusiasts, underscoring the boundless possibilities Flutter brings to digital innovation. Excitement builds for the next wave of extraordinary applications shaping the future of mobile technology through Flutter’s lens.&lt;/p&gt;

&lt;p&gt;Feel free to reach out if you have any queries or encounter any problems with this code. Also, let me know how you like this article, as feedback.&lt;/p&gt;

&lt;p&gt;Thank You!&lt;/p&gt;

&lt;p&gt;Source: &lt;em&gt;&lt;a href="https://flutter.dev/showcase"&gt;https://flutter.dev/showcase&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>mobile</category>
      <category>android</category>
      <category>ios</category>
    </item>
    <item>
      <title>Implementing a Custom Theme for Better Player in Flutter</title>
      <dc:creator>Jenish MS</dc:creator>
      <pubDate>Fri, 19 Jan 2024 10:57:37 +0000</pubDate>
      <link>https://dev.to/jenishms/implementing-a-custom-player-theme-in-better-player-for-flutter-5h5m</link>
      <guid>https://dev.to/jenishms/implementing-a-custom-player-theme-in-better-player-for-flutter-5h5m</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In Flutter app development, incorporating videos into your application is a common requirement. To enhance the user experience and maintain visual consistency, it is essential to customize the appearance of video players. In this article, we will explore how to create a custom theme for the Better Player package in Flutter, enabling you to integrate and personalize video playback within your app seamlessly.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Getting Started with a Better Player:
&lt;/h2&gt;

&lt;p&gt;Before diving into customization, let’s first understand the Better Player package. Better Player is a feature-rich video player plugin for Flutter that offers various capabilities such as adaptive streaming, subtitles, and more. To begin, 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 plaintext"&gt;&lt;code&gt;dependencies:
  flutter:
    sdk: flutter
  better_player: ^x.x.x  # Replace with the latest version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import the package into your Flutter project:&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:better_player/better_player.dart';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Defining Custom Controls:
&lt;/h2&gt;

&lt;p&gt;Creating custom controls involves designing and implementing a user interface for media playback controls in applications. By customizing the controls, developers can tailor the appearance, behavior, and functionality to suit their specific needs. This process typically includes defining buttons, progress bars, time displays, volume controls, and other elements essential for media playback. Custom control builders empower developers to craft unique and immersive experiences for users, enhancing usability and visual appeal within media-intensive applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class CustomPlayerControl extends StatelessWidget {
  const CustomPlayerControl( {required this.controller, super.key});

  final BetterPlayerController controller;

  @override
  Widget build(BuildContext context) {
     // Add custom controls here
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This CustomPlayerControl comes to the top of the video player. Here we can add Play, Pause, Seek, Full Screen, Mute, etc. controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Define a Better Player Controller:
&lt;/h2&gt;

&lt;p&gt;Define a better player controller with the BetterPlayerConfiguration class. For a better player configuration, you should add a player theme and a custom controls builder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BetterPlayerController(
   BetterPlayerConfiguration(
     // Other configurations 
     playerTheme: BetterPlayerTheme.custom,
     customControlsBuilder: (videoController, onPlayerVisibilityChanged) =&amp;gt;
       CustomPlayerControl(controller: videoController),
     ),
   ),
   betterPlayerDataSource: BetterPlayerDataSource(
     BetterPlayerDataSourceType.network,
     'VIDEO_URL'),
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the player theme property, you should give BetterPlayerTheme.custom, and in the customControlsBuilder function, return the custom control widget.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Define a Better Player Video Widget:
&lt;/h2&gt;

&lt;p&gt;Define the Video player widget in the build method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: AspectRatio(
          aspectRatio: 16 / 9,
          child: BetterPlayer(controller: _videoController),
        ),
      ),
    );
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Result:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe886h1yoyyrvzxw3sh23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe886h1yoyyrvzxw3sh23.png" alt="Implementing a Custom Player Theme in Better Player for Flutter | Jenish MS" width="320" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Code:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;custom_player_control.page&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;import 'package:better_player/better_player.dart';
import 'package:bp_custom_theme/video_scrubber.widget.dart';
import 'package:flutter/material.dart';

class CustomPlayerControl extends StatelessWidget {
  const CustomPlayerControl({required this.controller, super.key});

  final BetterPlayerController controller;

  void _onTap() {
    controller.setControlsVisibility(true);
    if (controller.isPlaying()!) {
      controller.pause();
    } else {
      controller.play();
    }
  }

  void _controlVisibility() {
    controller.setControlsVisibility(true);
    Future.delayed(const Duration(seconds: 3))
        .then((value) =&amp;gt; controller.setControlsVisibility(false));
  }

  String _formatDuration(Duration? duration) {
    if (duration != null) {
      String minutes = duration.inMinutes.toString().padLeft(2, '0');
      String seconds = (duration.inSeconds % 60).toString().padLeft(2, '0');
      return '$minutes:$seconds';
    } else {
      return '00:00';
    }
  }

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: _controlVisibility,
      child: StreamBuilder(
        initialData: false,
        stream: controller.controlsVisibilityStream,
        builder: (context, snapshot) {
          return Stack(
            children: [
              Visibility(
                visible: snapshot.data!,
                child: Positioned(
                  child: Center(
                    child: FloatingActionButton(
                      onPressed: _onTap,
                      backgroundColor: Colors.black.withOpacity(0.7),
                      child: controller.isPlaying()!
                          ? const Icon(
                              Icons.pause,
                              color: Colors.white,
                              size: 40,
                            )
                          : const Icon(
                              Icons.play_arrow_rounded,
                              color: Colors.white,
                              size: 50,
                            ),
                    ),
                  ),
                ),
              ),
              Positioned(
                left: 10,
                right: 10,
                bottom: 8,
                child: ValueListenableBuilder(
                  valueListenable: controller.videoPlayerController!,
                  builder: (context, value, child) {
                    return Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Container(
                              height: 36,
                              width: 100,
                              alignment: Alignment.center,
                              decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(50),
                                shape: BoxShape.rectangle,
                                color: Colors.black.withOpacity(0.5),
                              ),
                              child: Text(
                                '${_formatDuration(value.position)}/${_formatDuration(value.duration)}',
                                style: const TextStyle(color: Colors.white),
                              ),
                            ),
                            IconButton(
                              onPressed: () async {
                                controller.toggleFullScreen();
                              },
                              icon: const Icon(
                                Icons.crop_free_rounded,
                                size: 22,
                                color: Colors.white,
                              ),
                            )
                          ],
                        ),
                        VideoScrubber(
                          controller: controller,
                          playerValue: value,
                        )
                      ],
                    );
                  },
                ),
              ),
            ],
          );
        },
      ),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;video_scrubber.dart&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;import 'package:better_player/better_player.dart';
import 'package:flutter/material.dart';

class VideoScrubber extends StatefulWidget {
  const VideoScrubber(
      {required this.playerValue, required this.controller, super.key});
  final VideoPlayerValue playerValue;
  final BetterPlayerController controller;

  @override
  VideoScrubberState createState() =&amp;gt; VideoScrubberState();
}

class VideoScrubberState extends State&amp;lt;VideoScrubber&amp;gt; {
  double _value = 0.0;

  @override
  void initState() {
    super.initState();
  }

  @override
  void didUpdateWidget(covariant VideoScrubber oldWidget) {
    super.didUpdateWidget(oldWidget);
    int position = oldWidget.playerValue.position.inSeconds;
    int duration = oldWidget.playerValue.duration?.inSeconds ?? 0;
    setState(() {
      _value = position / duration;
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return SliderTheme(
      data: SliderTheme.of(context).copyWith(
          thumbShape: CustomThumbShape(), // Custom thumb shape
          overlayShape: SliderComponentShape.noOverlay),
      child: Slider(
        value: _value,
        inactiveColor: Colors.grey,
        min: 0.0,
        max: 1.0,
        onChanged: (newValue) {
          setState(() {
            _value = newValue;
          });
          final newProgress = Duration(
              milliseconds: (_value *
                      widget.controller.videoPlayerController!.value.duration!
                          .inMilliseconds)
                  .toInt());
          widget.controller.seekTo(newProgress);
        },
      ),
    );
  }
}

class CustomThumbShape extends SliderComponentShape {
  final double thumbRadius = 6.0;

  @override
  Size getPreferredSize(bool isEnabled, bool isDiscrete) {
    return Size.fromRadius(thumbRadius);
  }

  @override
  void paint(
    PaintingContext context,
    Offset center, {
    required Animation&amp;lt;double&amp;gt; activationAnimation,
    required Animation&amp;lt;double&amp;gt; enableAnimation,
    required bool isDiscrete,
    required TextPainter labelPainter,
    required RenderBox parentBox,
    required SliderThemeData sliderTheme,
    required TextDirection textDirection,
    required double value,
    required double textScaleFactor,
    required Size sizeWithOverflow,
  }) {
    final canvas = context.canvas;
    final fillPaint = Paint()
      ..color = sliderTheme.thumbColor!
      ..style = PaintingStyle.fill;

    canvas.drawCircle(center, thumbRadius, fillPaint);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub Repository Link: &lt;a href="https://github.com/JenishMS/bp_custom_theme"&gt;https://github.com/JenishMS/bp_custom_theme&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Feel free to reach out if you have some queries or encounter any problems with this code. Also, let me know how you like this article, as feedback.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  7. Conclusion:
&lt;/h2&gt;

&lt;p&gt;The Better Player package offers a powerful and customizable video player solution for Flutter applications. By creating a custom theme, you can tailor the appearance of the player controls, progress bar, captions, and more to match your app’s design language. This level of customization elevates the user experience and ensures visual consistency throughout your application. So go ahead, unleash your creativity, and enhance your Flutter app’s video playback with the Better Player package’s custom theme capabilities.&lt;/p&gt;

&lt;p&gt;Thank you, feedback is appreciated!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>appdevelopment</category>
      <category>fluttervideoplayer</category>
      <category>videoplayer</category>
    </item>
    <item>
      <title>How to Implement Resumable File Uploads toAzure Blob Storage in Flutter</title>
      <dc:creator>Jenish MS</dc:creator>
      <pubDate>Fri, 28 Jul 2023 17:19:28 +0000</pubDate>
      <link>https://dev.to/jenishms/how-to-implement-resumable-file-uploads-toazure-blob-storage-in-flutter-e6a</link>
      <guid>https://dev.to/jenishms/how-to-implement-resumable-file-uploads-toazure-blob-storage-in-flutter-e6a</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;In today’s digital era, file uploads are a crucial part of many mobile applications. However, handling large file uploads can be challenging due to network instability and limited bandwidth. To address this issue, developers can implement resumable file uploads, which allow the upload process to resume from the point of failure, ensuring a smoother user experience. In this blog, we will explore how to achieve resumable file uploads to Azure Blob Storage in Flutter, utilizing an example Flutter package to simplify the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;p&gt;Before we dive into the implementation, make sure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flutter development environment setup.&lt;/li&gt;
&lt;li&gt;An Azure Blob Storage with the necessary access keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Choosing the Flutter Package:
&lt;/h2&gt;

&lt;p&gt;To streamline the process, we’ll use the “&lt;em&gt;&lt;a href="https://pub.dev/packages/resumable_upload"&gt;resumable_upload&lt;/a&gt;&lt;/em&gt;” package, which is a popular Flutter plugin for handling file uploads. It provides resumable file upload capabilities and works seamlessly with Azure Blob Storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Setting Up the Flutter Project
&lt;/h2&gt;

&lt;p&gt;Start by creating a new Flutter project or using an existing one. Ensure you’ve updated your pubspec.yaml file to include the “&lt;em&gt;&lt;a href="https://pub.dev/packages/resumable_upload"&gt;resumable_upload&lt;/a&gt;&lt;/em&gt;” package:&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:
    sdk: flutter
  resumable_upload: ^0.0.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, run &lt;code&gt;flutter pub get&lt;/code&gt; to install the package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Configuring Azure Blob Storage
&lt;/h2&gt;

&lt;p&gt;Before we proceed with the code implementation, you need to configure your Azure Blob Storage to store the uploaded files. Make sure to note down the container’s URL and access keys, as we’ll use them in the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Implementing the Resumable File Upload
&lt;/h2&gt;

&lt;p&gt;In this step, we’ll implement the resumable file upload functionality using the “&lt;a href="https://pub.dev/packages/resumable_upload"&gt;resumable_upload&lt;/a&gt;” package. First, import the necessary dependencies:&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:flutter/material.dart';
import 'package:resumable_upload/resumable_upload.dart';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, initialize the uploader:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UploadClient client = UploadClient(
        file: // Provide the file object to upload,
        cache: LocalCache(),
        blobConfig: BlobConfig(
            accountName: 'AZURE_BLOB_ACCOUNT_NAME',
            containerName: 'AZURE_BLOB_NAME',
            blobName: 'AZURE_BLOB_NAME',
            sasToken: 'AZURE_Sas_TOKEN'),
    )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a function to handle the file upload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Future&amp;lt;void&amp;gt; uploadFile() async {
  client.uploadBlob(
        onProgress: (count, total, response) {
          final num = ((count / total) * 100).toInt().toString();
          print('Uploading $num %')
        },
        onComplete: (path, response) {
          print('File uploaded successfully.');
        },
      );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Triggering the Upload
&lt;/h2&gt;

&lt;p&gt;Now, you can trigger the file upload process, for example, in response to a button tap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ElevatedButton(
  onPressed: () {
    uploadFile();
  },
  child: Text('Upload File'),
),
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;Congratulations! You’ve successfully implemented resumable file uploads to Azure Blob Storage in Flutter using the “resumable_upload” package. With this functionality in place, your users can enjoy a smooth file upload experience, even when dealing with unreliable network connections.&lt;/p&gt;

&lt;p&gt;Remember to handle any potential error scenarios and provide appropriate feedback to users during the upload process. You can further enhance the user experience by adding indicators and error handling to make the upload process more transparent.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>android</category>
      <category>ios</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
