Flutter

836 readers
1 users here now

Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC

founded 2 years ago
MODERATORS
1
2
3
4
 
 

Hey there. I just released a plugin that helps you spawn an isolate in an Android Foreground Service. The isolate stays alive even if the main activity is killed. You can easily communicate with and reconnect to the isolate using my isolate_channel package.

5
6
 
 

I've only ever built Android/Web apps with Flutter, but I had a request to get one of my apps working on iPhone. I knew I wasn't going to have fun before I started, and I wasn't wrong. But I managed to get an Apple Developer Account, jump through the hoops for adhoc distribution profile and certificates, built an account at Codemagic and succeeded to get build to work, managed to downgrade Flutter until I could get an iOS 12.0 build to install on an iPhone6, but now it fails when it loads and I have no clue how to troubleshoot this.

If it were android, I'd have it hooked up to my dev station and run debug version to monitor, but this inscrutable chunk of plastic and glass doesn't seem to work that way. I don't have a Mac box to dev on, so I'm left with running CI builds that I pull down via Diawi to the device, but it's a black box from there.

Is there a way to do anything useful on a Linux dev station with these things?

God, if Google's "developer registration" is anything like this nightmare, I'm going to work on helping dev a Linux phone fulltime.

7
8
9
 
 

Hello again! I have finally deployed a version of the Hive documentation site updated to reflect all the changes in Hive CE. This should serve as a single source of truth for the best practices when using Hive CE, as well as a more accessible getting started guide for developers unfamiliar with the original Hive package.

Please have a look and let me know what you think!

10
 
 

After many months of work, it is finally here! You can now use the Hive CE Inspector DevTools extension to quickly view the contents of any Hive box open in your application with live updates.

See a video of the inspector in action here: https://github.com/IO-Design-Team/hive_ce/issues/52#issuecomment-3300976432

The inspector builds upon previous work by automatically reading the Hive schema (hive_adapters.g.yaml) from your project and using it to deserialize raw box data into a human-readable format. This does mean, however, that your project must be using the GenerateAdapters annotation to generate type adapters. Data created by HiveType annotations and custom adapters will only be viewable as raw binary data.

Please try it out and let me know your thoughts!

11
12
13
 
 

I made a notes app to fit my own needs on #Linux. I used @flutter . If people would be willing to play around with it a little and give feedback, that would be great!

#flutter #notes #ubuntu

https://github.com/timappledotcom/jotdown/tree/main

14
 
 

¡Gracias también a Flutter Málaga por ser parte de #OpenSouthCode25! 💙🩵
Conecta a devs con intereses en Flutter, compartiendo experiencias, conocimiento… ¡y buen rollo! 😄
Anímate y empieza a crear apps cross-platform con @flutter 🚀

15
 
 

🧩 Exploring dynamic vector image coloring in Flutter?

Part 2 of my ImageColorSwitcher series @Medium article delves into SVG handling using the flutter_svg package, demonstrating how to apply color filters and handle interactive coloring.

If you're building themeable UIs or visual editors, this might be for you.

🔗 ImageColorSwitcher in Flutter: Part 2-Vector Image Coloring
https://medium.com/gitconnected/imagecolorswitcher-in-flutter-part-2-vector-image-coloring-97509fd6a90a

@flutter @FlutterComm #MobileApps @android @thepracticaldev #android #app #ui #technology #foss

16
 
 

🖼️ Want to build dynamic color filters for images in Flutter?

In this @Medium article, I walk through raster image color manipulation using ColorFiltered, BlendMode, and custom sliders — all explained with visuals and Flutter-native logic.

Perfect for devs building interactive image apps or theme switchers.

🔗 ImageColorSwitcher in Flutter: Part 1 Raster Image Coloring --https://levelup.gitconnected.com/imagecolorswitcher-in-flutter-part-1-raster-image-coloring-90f2cd0c8788

@flutter @FlutterComm #MobileApps @android #android @thepracticaldev #ui #apps #color #technology

17
18
19
 
 

Highlights

  • Hot reload on the web (Experimental).
  • New Expansible widget that makes it easier to create widgets that expand and collapse.
  • Many Material and Cupertino additions.
  • Several accessibility improvements.
  • Progress on multi-window support.
  • Desktop thread merging.
  • New Flutter Property Editor for IDEs.

Dart update here: https://kbin.earth/m/dart@programming.dev/t/1358229

20
 
 

I'm trying to implement the OpenContainer transition for go_router in Flutter. It seems like no matter what I do, the end result is choppy. :/

I'm using the native Transition widgets as well as the relatively new SnapshotWidget, but to no avail. Should I maybe use a custom painter? Would that improve performance?

Please take a look at the code below and let me know if you see any ways that I could improve performance.


Here's my attempt at an OpenContainer transition for go_router:

import 'package:flutter/material.dart';
import 'package:your_project_name_xxx/ui_models/container_transition_extra.dart';

class ContainerTransition extends StatefulWidget {
  final ContainerTransitionExtra extra;
  final Animation<double> animation;
  final Widget? sourceWidget;
  final Widget targetWidget;

  const ContainerTransition({
    super.key,
    required this.extra,
    required this.animation,
    required this.sourceWidget,
    required this.targetWidget,
  });

  @override
  State<ContainerTransition> createState() => _ContainerTransitionState();
}

class _ContainerTransitionState extends State<ContainerTransition> {
  static final _toTween = Tween<double>(begin: 0, end: 1);
  static final _fromTween = Tween<double>(begin: 1, end: 0);

  late SnapshotController _snapshotController;
  late CurvedAnimation _curvedAnimation;
  late CurvedAnimation _sourceAnimation;
  late CurvedAnimation _targetAnimation;

  late RelativeRect? _sourcePosition;
  late Animation<double> _scrimOpacityAnimation;
  late Animation<double> _sourceOpacityAnimation;
  late Animation<double> _targetOpacityAnimation;
  late Animation<BorderRadius?> _containerRadiusAnimation;
  late Animation<RelativeRect> _containerPositionAnimation;

  @override
  void initState() {
    super.initState();
    _sourcePosition = widget.extra.tween.begin;
    _snapshotController = SnapshotController(allowSnapshotting: true);
    _curvedAnimation = CurvedAnimation(
      parent: widget.animation,
      curve: Curves.easeInOut,
    );
    _curvedAnimation.addStatusListener((status) {
      if (status.isAnimating) {
        _snapshotController.allowSnapshotting = true;
      } else if (status.isCompleted || status.isDismissed) {
        _snapshotController.allowSnapshotting = false;
      }
    });
    _sourceAnimation = CurvedAnimation(
      parent: _curvedAnimation,
      curve: Interval(0, 1 / 3),
    );
    _targetAnimation = CurvedAnimation(
      parent: _curvedAnimation,
      curve: Interval(1 / 3, 1),
    );
    _scrimOpacityAnimation = _toTween.animate(_sourceAnimation);
    _sourceOpacityAnimation = _fromTween.animate(_sourceAnimation);
    _targetOpacityAnimation = _toTween.animate(_targetAnimation);
    _containerRadiusAnimation = BorderRadiusTween(
            begin: BorderRadius.circular(widget.extra.containerRadius),
            end: BorderRadius.zero)
        .animate(_curvedAnimation);
    _containerPositionAnimation = _curvedAnimation.drive(widget.extra.tween);
  }

  @override
  void dispose() {
    _snapshotController.dispose();
    _sourceAnimation.dispose();
    _targetAnimation.dispose();
    _curvedAnimation.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Positioned.fill(
          child: FadeTransition(
            opacity: _scrimOpacityAnimation,
            child: ColoredBox(color: widget.extra.scrimColor),
          ),
        ),
        PositionedTransition(
          rect: _containerPositionAnimation,
          child: DecoratedBox(
            decoration: BoxDecoration(
              borderRadius: _containerRadiusAnimation.value,
              color: widget.extra.containerColor,
            ),
            child: FadeTransition(
              opacity: _targetOpacityAnimation,
              child: widget.targetWidget,
            ),
          ),
        ),
        if (_sourcePosition != null)
          Positioned.fromRelativeRect(
            rect: _sourcePosition!,
            child: FadeTransition(
              opacity: _sourceOpacityAnimation,
              child: widget.sourceWidget,
            ),
          ),
      ],
    );
  }
}

Here's how I'm building the route:

Page<T> buildContainerRoute<T>(
    BuildContext context,
    GoRouterState state,
    Ref ref,
    Widget child,
  ) {
    final containerExtra = state.extra;

    if (containerExtra is ContainerTransitionExtra) {
      final registryTag = containerExtra.sourceBuilderTag;
      final registryBuilder =
          registryTag != null ? SourceBuilderRegistry().get(registryTag) : null;
      if (registryBuilder != null) {
        if (registryBuilder.wasUsedAlready) {
          SourceBuilderRegistry().unregister(registryTag!);
        } else {
          SourceBuilderRegistry().markAsUsed(registryTag!);
        }
      }
      return CustomTransitionPage<T>(
        key: state.pageKey,
        child: child,
        transitionDuration: Durations.medium2,
        reverseTransitionDuration: Durations.medium1,
        transitionsBuilder: (context, animation, secondaryAnimation, child) {
          return ContainerTransition(
            animation: animation,
            extra: containerExtra,
            sourceWidget:
                Center(child: registryBuilder?.registryItem.call(context)),
            targetWidget: ClipRect(
              child: OverflowBox(
                alignment: Alignment.topCenter,
                maxWidth: containerExtra.cachedMaxWidth,
                maxHeight: containerExtra.cachedMaxHeight,
                child: child,
              ),
            ),
          );
        },
      );
    } else {
      if (!kIsWeb && Platform.isAndroid) {
        return MaterialPage(key: state.pageKey, child: child);
      } else {
        return CupertinoPage(key: state.pageKey, child: child);
      }
    }
  }
21
22
 
 

Hey Flutter devs! I'm excited to announce the release of Hive CE v2.11.0-pre, introducing a new interface called IsolatedHive—a safe way to use Hive across multiple isolates.

What's New:

  • IsolatedHive Interface: Enables safe Hive usage across isolates by maintaining its own dedicated isolate for database operations. It utilizes an IsolateNameServer behind the scenes to locate the Hive isolate.
  • Flutter Integration: Simply call IsolatedHive.initFlutter from hive_ce_flutter to automatically set things up to use Flutter's built-in IsolateNameServer.
  • Generated Extensions: The latest hive_ce_generator now provides the same easy-to-use registerAdapters extension on IsolatedHive.

Why Use IsolatedHive?

You might already be using isolates without realizing it! Common Flutter scenarios benefiting from isolate-safe Hive:

  • Desktop apps with multiple windows
  • Background task handling (flutter_workmanager, background_fetch, etc.)
  • Push notification processing

Note: Hive now prominently warns you if it detects unsafe isolate usage.

🎥 Multi-window Demo:

Video: https://files.catbox.moe/stb5gs.mov

Repo: https://github.com/Rexios80/hive_ce_multiwindow

Performance Considerations:

While IsolatedHive adds overhead due to isolate communication and isn't quite as fast as regular Hive CE, it's significantly faster and leaner than Hive v4:

Operations Hive CE Time IsolatedHive Time Hive CE Size Hive v4 Time Hive v4 Size
10 0.00 s 0.00 s 0.00 MB 0.00 s 1.00 MB
100 0.00 s 0.01 s 0.01 MB 0.01 s 1.00 MB
1000 0.02 s 0.03 s 0.11 MB 0.06 s 1.00 MB
10000 0.13 s 0.25 s 1.10 MB 0.64 s 5.00 MB
100000 1.40 s 2.64 s 10.97 MB 7.26 s 30.00 MB
1000000 19.94 s 41.50 s 109.67 MB 84.87 s 290.00 MB

Stability & Testing:

This pre-release is as stable as possible without real-world external testing—your feedback is invaluable!

Check it out, give it a spin, and share your experience:

Happy coding! 🐝✨

23
 
 

Hi everyone!

I've just released a new Dart package: isolate_channel. It provides a simple and familiar API for handling communication between Dart isolates, directly inspired by Flutter's MethodChannel and EventChannel APIs used for native plugin communication.

If you've ever found Dart isolate communication cumbersome or unintuitive, isolate_channel streamlines this process, making it feel as straightforward and familiar as working with Flutter plugin channels.

I built this package to prepare for upcoming isolate support in Hive CE, and it made that work a lot easier!

Check it out here: isolate_channel

I'd love your feedback or contributions!

24
 
 

cross-posted from: https://lemm.ee/post/56160274

I install Android Studio via flatpak, and this can cause flutter doctor to not be able to determine the version or to not recognize the installation at all. I've managed a hacky fix for this by running a few commands that I run as a simple script that I'm sharing here. If you use this, just close Android Stuido after it is opened; it seems to just need to be opened once in order to be recognized by flutter doctor.

#!/bin/bash

flutter config --android-studio-dir=/var/lib/flatpak/app/com.google.AndroidStudio/current/active/files/extra/android-studio

/var/lib/flatpak/app/com.google.AndroidStudio/current/active/files/extra/android-studio/bin/studio

flutter config --android-studio-dir=""

flutter doctor
25
8
submitted 1 year ago* (last edited 1 year ago) by neme@lemm.ee to c/flutter@programming.dev
view more: next ›