Achieve ~60 FPS, no matter how heavy the tree is to build/layout

Overview

flutter_smooth

logo

Achieve ~60 FPS, no matter how heavy the tree is to build/layout.

🎼 3-second video

output_small.mp4

(left = without smooth, right = smooth; captured by external camera to maximally demonstrate end-user perception. High-resolution video here.)

📚 1-minute explanation

Purpose

No matter how heavy the tree is to build/layout, it will run at (roughly) full FPS, feel smooth, has zero uncomfortable janks, with negligible overhead. (Detailed reports here)

Usage

Two possibilities:

  • Drop-in replacements: For common scenarios, add 6 characters ("Smooth") - ListView becomes SmoothListView, MaterialPageRoute becomes SmoothMaterialPageRoute.

  • Arbitrarily flexible builder: For complex cases, use SmoothBuilder(builder: ...) and put whatever you want to be smooth inside the builder.

🚀 What's next

The documentaiton - https://fzyzcjy.github.io/flutter_smooth/, with usage, demo, benchmark, insights, and more.

Note Feel free to create an issue if you have any questions/problems. I usually reply quickly within minutes if not hours, except for sleeping :)

Contributors

All Contributors

Thanks goes to these wonderful people (emoji key following all-contributors specification):

fzyzcjy
fzyzcjy

💻 📖 🤔
Ian Hickson
Ian Hickson

🤔
Dan Field
Dan Field

🤔
Jonah Williams
Jonah Williams

🤔
gaaclarke
gaaclarke

🤔
Nayuta403
Nayuta403

📖

More specifically, thanks for all these contributions:

  • @Hixie (Flutter team): Consider details of my several proposals to the Flutter framework/engine such as requiring zero-overhead principle. Construct concrete cases when the initial proposal becomes fragile.
  • @dnfield (Flutter team): Provide a canonical janky case inside Flutter framework to help prototyping. Point out slowness of sync generators which avoids detouring.
  • @jonahwilliams (Flutter team): Elaborate shortcomings of the old gesture system proposal (later I made a much more natural one).
  • @gaaclarke (Flutter team): Share his pet theory that slowness is caused by memory locality, indicating another potential application of the package.
  • @Nayuta403: Fix link.
Comments
  • Reproduce `list_text_layout.dart` and demonstrate how flutter_smooth solves it

    Reproduce `list_text_layout.dart` and demonstrate how flutter_smooth solves it

    @dnfield in https://discord.com/channels/608014603317936148/1039667632342835250/1039710167329165342


    Remark: I will mark a lot of my comments below as resolved, since they are solely used as external memory of my brain instead of real discussions with people interested in this thread. (Originally thought only me in this thread so do so)

    opened by fzyzcjy 35
  • compile flutter engine ref by flutter_smooth always get  Error, No named parameter with the name 'fallbackVsyncTargetTime'.

    compile flutter engine ref by flutter_smooth always get Error, No named parameter with the name 'fallbackVsyncTargetTime'.

    Is your feature request related to a problem? Please describe. $./flutter/tools/gn --unoptimized --no-goma --no-prebuilt-dart-sdk $ ninja -C out/host_debug_unopt

    in engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine/lib/ui/window.dart 265 line is still as void render(Scene scene) => _render(scene);

    Describe the solution you'd like how do i compile engine/lib/ui/window.dart into dart sdk? i search google for long time, but no one explain engine compile with dart sdk

    opened by vickyleu 24
  • Add motivating benchmark for flutter engine PR 36911 (not benchmark for flutter_smooth, but for that specific PR)

    Add motivating benchmark for flutter engine PR 36911 (not benchmark for flutter_smooth, but for that specific PR)

    Required by https://github.com/flutter/engine/pull/36911

    As dnfield points out, I should:

    • [ ] we need some motivating benchmarks that clearly show what benefits would be gained here -> this issue
    • [x] and we need to see that changes to this won't negatively impact existing benchmarks/users -> later (since I do not have access to run skia perf?)

    code should be at https://github.com/fzyzcjy/engine/tree/feat/await-vsync-directly-call

    opened by fzyzcjy 14
  • Current status

    Current status

    Please refer to

    1. The doc https://cjycode.com/flutter_smooth/
    2. ~~The project board https://github.com/users/fzyzcjy/projects/5~~ Just refer to issue section since some things are in issue but not in project: https://github.com/fzyzcjy/flutter_smooth/issues
    opened by fzyzcjy 9
  • getting error after adding

    getting error after adding

    Describe the bug i have tried to run smooth example app but i have got these errors

    `../smooth/lib/src/infra/extra_event_dispatcher.dart:48:9: Error: No named parameter with the name 'filter'. filter: (entry) { ^^^^^^ ../smooth/lib/src/infra/extra_event_dispatcher.dart:114:24: Error: The method 'readEnginePendingEventsAndClear' isn't defined for the class 'GestureBinding'.

    • 'GestureBinding' is from 'package:flutter/src/gestures/binding.dart' ('/F:/flutter/packages/flutter/lib/src/gestures/binding.dart'). Try correcting the name to the name of an existing method, or defining a method named 'readEnginePendingEventsAndClear'. gestureBinding.readEnginePendingEventsAndClear(); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/binding.dart:130:17: Error: Type 'HitTestEntryFilter' not found. {required HitTestEntryFilter? filter}) { ^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/binding.dart:301:7: Error: Class 'WidgetsFlutterBinding with SmoothSchedulerBindingMixin, SmoothGestureBindingMixin with SmoothRendererBindingMixin' inherits multiple members named 'GestureBinding.dispatchEvent%RendererBinding.dispatchEvent%GestureBinding.dispatchEvent%RendererBinding.dispatchEvent%SmoothGestureBindingMixin.dispatchEvent' with incompatible signatures. Try adding a declaration of 'GestureBinding.dispatchEvent%RendererBinding.dispatchEvent%GestureBinding.dispatchEvent%RendererBinding.dispatchEvent%SmoothGestureBindingMixin.dispatchEvent' to 'WidgetsFlutterBinding with SmoothSchedulerBindingMixin, SmoothGestureBindingMixin with SmoothRendererBindingMixin'. class SmoothWidgetsFlutterBinding extends WidgetsFlutterBinding ^ /F:/flutter/packages/flutter/lib/src/gestures/binding.dart:415:8: Context: This is one of the overridden members. void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... /F:/flutter/packages/flutter/lib/src/rendering/binding.dart:328:8: Context: This is one of the overridden members. void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) { ^^^^^^^^^^^^^ ../smooth/lib/src/infra/binding.dart:301:7: Error: Class 'WidgetsFlutterBinding with SmoothSchedulerBindingMixin, SmoothGestureBindingMixin, SmoothRendererBindingMixin with SmoothWidgetsBindingMixin' inherits multiple members named 'GestureBinding.dispatchEvent%RendererBinding.dispatchEvent%GestureBinding.dispatchEvent%RendererBinding.dispatchEvent%SmoothGestureBindingMixin.dispatchEvent%RendererBinding.dispatchEvent' with incompatible signatures. Try adding a declaration of 'GestureBinding.dispatchEvent%RendererBinding.dispatchEvent%GestureBinding.dispatchEvent%RendererBinding.dispatchEvent%SmoothGestureBindingMixin.dispatchEvent%RendererBinding.dispatchEvent' to 'WidgetsFlutterBinding with SmoothSchedulerBindingMixin, SmoothGestureBindingMixin, SmoothRendererBindingMixin with SmoothWidgetsBindingMixin'. class SmoothWidgetsFlutterBinding extends WidgetsFlutterBinding ^ /F:/flutter/packages/flutter/lib/src/gestures/binding.dart:415:8: Context: This is one of the overridden members. void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^... /F:/flutter/packages/flutter/lib/src/gestures/binding.dart:415:8: Context: This is one of the overridden members. void dispatchEvent(PointerEvent event, HitTestResult? hitTestResult) { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/binding.dart:60:9: Error: The method 'adjustForEpoch' isn't defined for the class 'SmoothSchedulerBindingMixin'.
    • 'SmoothSchedulerBindingMixin' is from 'package:smooth/src/infra/binding.dart' ('../smooth/lib/src/infra/binding.dart'). Try correcting the name to the name of an existing method, or defining a method named 'adjustForEpoch'. adjustForEpoch(rawTimeStamp ?? currentSystemFrameTimeStamp)); ^^^^^^^^^^^^^^ ../smooth/lib/src/infra/binding.dart:130:17: Error: 'HitTestEntryFilter' isn't a type. {required HitTestEntryFilter? filter}) { ^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/binding.dart:140:49: Error: No named parameter with the name 'filter'. super.dispatchEvent(event, hitTestResult, filter: filter); ^^^^^^ ../smooth/lib/src/infra/binding.dart:169:9: Error: No named parameter with the name 'fallbackVsyncTargetTime'. fallbackVsyncTargetTime: effectiveFallbackVsyncTargetTime, ^^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/binding.dart:217:11: Error: No named parameter with the name 'forceDirectlyCallNextVsyncTargetTime'. forceDirectlyCallNextVsyncTargetTime: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/proxy.dart:13:53: Error: The getter 'nodesNeedingPaint' isn't defined for the class 'PipelineOwner'.
    • 'PipelineOwner' is from 'package:flutter/src/rendering/object.dart' ('/F:/flutter/packages/flutter/lib/src/rendering/object.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'nodesNeedingPaint'. List get nodesNeedingPaint => inner.nodesNeedingPaint; ^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/proxy.dart:141:27: Error: No named parameter with the name 'fallbackVsyncTargetTime'. inner.render(scene, fallbackVsyncTargetTime: fallbackVsyncTargetTime); ^^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/proxy.dart:259:11: Error: No named parameter with the name 'forceDirectlyCallNextVsyncTargetTime'. forceDirectlyCallNextVsyncTargetTime: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/auxiliary_tree_pack.dart:36:27: Error: Method not found: 'TickerRegistry'. final _tickerRegistry = TickerRegistry(); ^^^^^^^^^^^^^^ ../smooth/lib/src/infra/auxiliary_tree_pack.dart:58:14: Error: The method 'TickerRegistryInheritedWidget' isn't defined for the class 'AuxiliaryTreePack'.
    • 'AuxiliaryTreePack' is from 'package:smooth/src/infra/auxiliary_tree_pack.dart' ('../smooth/lib/src/infra/auxiliary_tree_pack.dart'). Try correcting the name to the name of an existing method, or defining a method named 'TickerRegistryInheritedWidget'. child: TickerRegistryInheritedWidget( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/auxiliary_tree_pack.dart:181:26: Error: Unexpected type 'invalid-type' of a spread. Expected 'dynamic' or an Iterable. ..._tickerRegistry.tickers, ^ ../smooth/lib/src/infra/auxiliary_tree_pack.dart:225:16: Error: Setter not found: 'debugActiveLayout'. RenderObject.debugActiveLayout = null; ^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/auxiliary_tree_pack.dart:229:18: Error: Setter not found: 'debugActiveLayout'. RenderObject.debugActiveLayout = oldDebugActiveLayout; ^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/actor.dart:135:9: Error: No named parameter with the name 'fallbackVsyncTargetTime'. fallbackVsyncTargetTime: ^^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/infra/actor.dart:143:34: Error: The method 'notifyIdle' isn't defined for the class 'PlatformDispatcher'.
    • 'PlatformDispatcher' is from 'dart:ui'. Try correcting the name to the name of an existing method, or defining a method named 'notifyIdle'. binding.platformDispatcher.notifyIdle( ^^^^^^^^^^ ../smooth/lib/src/drop_in/page_route/page_routes.dart:77:3: Error: The superclass, 'PageRouteBuilder with SmoothPageRouteMixin', has no unnamed constructor that takes no arguments. SmoothPageRouteBuilder({ ^^^^^^^^^^^^^^^^^^^^^^ ../smooth/lib/src/drop_in/page_route/page_routes.dart:104:11: Error: No named parameter with the name 'allowSnapshotting'. allowSnapshotting: false, ^^^^^^^^^^^^^^^^^ ../smooth/lib/src/drop_in/list_view/controller.dart:71:25: Error: The getter 'controller' isn't defined for the class '_SmoothBallisticScrollActivity'.
    • '_SmoothBallisticScrollActivity' is from 'package:smooth/src/drop_in/list_view/controller.dart' ('../smooth/lib/src/drop_in/list_view/controller.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'controller'. ?.controller.lastElapsedDuration?.inMicroseconds ?? ^^^^^^^^^^ ../smooth/lib/src/drop_in/list_view/controller.dart:140:3: Error: The superclass, 'BallisticScrollActivity', has no unnamed constructor that takes no arguments. _SmoothBallisticScrollActivity.raw( ^^^ ../smooth/lib/src/drop_in/list_view/shift.dart:352:36: Error: The getter 'startTime' isn't defined for the class 'Ticker'.
    • 'Ticker' is from 'package:flutter/src/scheduler/ticker.dart' ('/F:/flutter/packages/flutter/lib/src/scheduler/ticker.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'startTime'. final tickTimeStamp = _ticker!.startTime! + selfTickerElapsed; ^^^^^^^^^ ../smooth/lib/src/drop_in/list_view/shift.dart:356:59: Error: The getter 'startTime' isn't defined for the class 'Ticker'.
    • 'Ticker' is from 'package:flutter/src/scheduler/ticker.dart' ('/F:/flutter/packages/flutter/lib/src/scheduler/ticker.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'startTime'. final ballisticTickerStartTime = info.ballisticTicker.startTime; ^^^^^^^^^ ../smooth/lib/src/drop_in/list_view/list_view.dart:34:28: Error: The argument type 'Widget? Function(BuildContext, int)' can't be assigned to the parameter type 'Widget Function(BuildContext, int)' because 'Widget?' is nullable and 'Widget' isn't.
    • 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('/F:/flutter/packages/flutter/lib/src/widgets/framework.dart').
    • 'BuildContext' is from 'package:flutter/src/widgets/framework.dart' ('/F:/flutter/packages/flutter/lib/src/widgets/framework.dart'). itemBuilder: itemBuilder, ^ ../smooth/lib/src/drop_in/list_view/list_view.dart:116:22: Error: A value of type 'Widget?' can't be returned from a function with return type 'Widget' because 'Widget?' is nullable and 'Widget' isn't.
    • 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('/F:/flutter/packages/flutter/lib/src/widgets/framework.dart'). return widget.itemBuilder(context, index - 1);`

    To Reproduce Steps to reproduce the behavior:

    1. open example project
    2. Click on run
    3. click on run tab
    4. See error
    opened by sparkmobi 8
  • Implement PR

    Implement PR "Fix jank and large-jumping frame by controlling rasterizer ending time"

    • https://github.com/flutter/engine/pull/36837
    • https://github.com/flutter/engine/pull/37340

    next steps

    • [x] correct timing
    • [x] fix compile error
    • [x] do not use real sleep
    • [x] extract "rasterizer sleep strategy" to a separate class
    • [x] add tests to strategy
    • [ ] pass tests of strategy

    Question: how to do correct timing?

    https://github.com/fzyzcjy/flutter_smooth/issues/165

    opened by fzyzcjy 6
  • Write an article discussing how it is implemented

    Write an article discussing how it is implemented

    Possible outline

    • preemptRender
    • Brake
    • gesture subsystem
    • how SmoothListView is implemented (also serve as an example to use SmoothBuilder)
    • how SmoothMaterialPageRoute is implemented
    opened by fzyzcjy 5
  • Copy all discussions into the repo as an archive

    Copy all discussions into the repo as an archive

    Otherwise all these are so dispersed, and is hard to search...

    • [x] the main github issue
    • [x] several other github issues
    • [x] design doc (google doc)
    • [x] google doc comments (a lot)
    • [x] discord channel
    • [x] that one discord "threads" called "Preempt Render"
    • [x] the several github PRs, also with discussions there

    what to copy

    • [x] the text
    • [ ] the images (cannot be links - external links can die)
    • [x] the timestamp (otherwise cannot see relationship between messages)
    • [x] the author (who said it)
    • [x] time of retrivial (updates can happen later)
    • [x] link to the original content

    How to download each of them?

    github issue, github pr

    e.g. gh issue view 38 --json author,body,comments

    images in it

    maybe write a small script

    google doc content

    maybe just copy-and-paste

    images in it

    maybe done manually

    google doc comments

    https://stackoverflow.com/questions/66103464/export-google-docs-comments-into-google-sheets-along-with-highlighted-text

    discord

    https://github.com/Tyrrrz/DiscordChatExporter

    opened by fzyzcjy 5
  • Bump loader-utils from 2.0.3 to 2.0.4 in /website

    Bump loader-utils from 2.0.3 to 2.0.4 in /website

    Bumps loader-utils from 2.0.3 to 2.0.4.

    Release notes

    Sourced from loader-utils's releases.

    v2.0.4

    2.0.4 (2022-11-11)

    Bug Fixes

    Changelog

    Sourced from loader-utils's changelog.

    2.0.4 (2022-11-11)

    Bug Fixes

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the Security Alerts page.
    dependencies javascript 
    opened by dependabot[bot] 0
  • Discuss pull-based model, since dnfield mentions

    Discuss pull-based model, since dnfield mentions "... a major architectural change we'd need more time to reason about"

    1

    • https://github.com/flutter/engine/pull/36916

    This is not the only thing that would need peeking,a nd creating this kind of "pull" based model is a major architectural change we'd need more time to reason about. I'm going to close this PR to get it off of review queues for now - tests are not passing and it is not clear that this API is the desirable one to expose to developers to achieve the larger goals you're discussing.

    2

    • https://github.com/flutter/engine/pull/36607

    I'm going to close this to remove it from review queues. As I'm mentioning in some other PRs, let's discuss further on discord.

    opened by fzyzcjy 0
  • Think and discuss two PRs related to NotifyIdle

    Think and discuss two PRs related to NotifyIdle

    https://github.com/flutter/engine/pull/36797

    We don't want to expose this kind of internal of the VM to users. Perhaps it would be more appropriate to expose a different API around whether an animation is occurring currently, although I think @iskakaushik has already done some work on that.

    https://github.com/flutter/engine/pull/36834

    Same problems as the other NotifyIdle PR - these are details we don't want to expose to users. NotifyIdle might not do anything, or it might do a lot more than the user expects. In all honesty, it would be nice to get rid of it entirely since it is hard to reason about and seems to come out wrong very frequently. If users can change this arbitrarily it will make it much harder to reason about what's going on in an application. Closing this to remove from review queues. There is definitely work to do around NotifyIdle, but I think we'll need some cooperation from the dart VM team on it.

    opened by fzyzcjy 4
A simple FPS monitor for Flutter

statsfl - A simple FPS monitor for Flutter ?? Installation dependencies: statsfl: ^2.2.0+1 ⚙ Import import 'package:statsfl/statsfl.dart'; ??️ Usage

gskinner team 63 Nov 22, 2022
A grid-based layout system for Flutter, inspired by CSS Grid Layout

Flutter Layout Grid A powerful grid layout system for Flutter, optimized for complex user interface design. Click images to see their code ✨ Featuring

Felt 307 Dec 24, 2022
A grid-based layout system for Flutter, inspired by CSS Grid Layout

Flutter Layout Grid A powerful grid layout system for Flutter, optimized for complex user interface design. Click images to see their code ✨ Featuring

Felt 307 Dec 24, 2022
Flutter After Layout - Brings functionality to execute code after the first layout of a widget has been performed

Flutter After Layout - Brings functionality to execute code after the first layout of a widget has been performed, i.e. after the first frame has been displayed. Maintainer: @slightfoot

Flutter Community 432 Jan 3, 2023
Learn to build a basic app layout using only Flutter & Dart

basic-flutter-layout Created by Thai Duong Do (Tad Wilson) for non-commercial pu

TAD 5 Oct 12, 2022
A beautiful app to help you achieve your goals🎯

Goalkeeper ?? A neat, nice looking Flutter app to keep track of your goals! It can be built for iOS and Android, and is available for free on the Play

Urmil Shroff 40 Dec 28, 2022
Dart Koans. Achieve enlightenment through failure.

Dart Koans This application is inspired by Ruby Koans. The idea is simple: You achieve enlightenment though a process of failures. As each failure is

Matthew Butler 41 Oct 3, 2022
RelativeScale is a simple custom sizing system for flutter widgets to achieve the same physical sizes across different devices.

RelativeScale is a simple custom sizing system for flutter widgets to achieve the same physical sizes across different devices. Usage It is VERY easy

xamantra 19 Nov 25, 2022
A Flutter package used to update widget tree dynamically

简体中文|English Fair is a lightweight package for Flutter, which can be used to update widget tree and state dynamically. This package is still at an ear

Wuba 1.8k Dec 30, 2022
Widget to count the amount of nested widget tree, useful in the dynamic construction of the interface when it is important to know the depth of widget.

widget_tree_depth_counter Widget Tree Depth Counter WidgetTreeDepthCounter is a simple widget to count the amount of nested widget tree, useful in the

Riccardo Cucia 4 Aug 1, 2022
Flutter package that provides you custom clippers to help you achieve various custom shapes.

flutter_custom_clippers Flutter package that provides you custom clippers to help you achieve various custom shapes. Usage To use this plugin, add flu

Damodar Lohani 291 Dec 23, 2022
Behruz Hurramov 0 Dec 29, 2021
SmallTask - Take small steps to achieve big things

SmallTask - Take small steps to achieve big things. Have you ever felt that when you are working on a project you kinda get confused about what to do?

Yuji 2 Mar 7, 2022
Flutter remote control - The main use of LongPressDraggable and DragTarget to achieve the universal remote control interaction effect.

Flutter remote control - The main use of LongPressDraggable and DragTarget to achieve the universal remote control interaction effect.

唯鹿 165 Jan 2, 2023
An app to save money and achieve your goal! Available on iOS & Android 🚀

BudgetMe An app that helps you save money and achieve your goal! Screenshots TestFlight & Google Play Beta License About This is an app to save money

Carlton Aikins 31 Nov 27, 2022
A quick and powerful Flutter layout with a bottom navbar.

What is bottom_nav_layout? It is a quick flutter app layout for building an app with a bottom nav bar. You can get an app with fluent behavior running

Mustafa Azyoksul 31 Dec 21, 2022
Example de layout in Flutter inspiration in Netflix App + Woody Woodpecker Characters

PicFlix Example de layout in Flutter inspiration in Netflix App + Woody Woodpecker Characters Cover extracted of https://twitter.com/winemcbride/statu

Tiago Danin 3 May 17, 2021
flutter development bootcamp layout challenge #2.1

MiCard App Challenge Hey folks! This app is the continuation of the layout_challenge_app. I coded this app from scratch because unfortunate things hap

Damla Çim 1 Jan 6, 2022
Layout of the flutter example.such as Row,Comlun,listview,Just for learning.

Just for learning ❤️ Star ❤️ the repo to support the project or ?? Follow Me.Thanks! Facebook Page Facebook Group QQ Group Developer Flutter Open Flut

Flutter开源社区 308 Nov 29, 2022