Code Monkey home page Code Monkey logo

gap's Introduction

Gap

Flutter widgets for easily adding gaps inside Flex widgets such as Columns and Rows or scrolling views.

Pub

Introduction

When it comes to add empty space between widgets inside a Column or a Row, we have multiple options:

  • We can either add a Padding around these widgets but it's very verbose
  • Or we can add SizedBox widgets between them.

Gap is another option. It's like SizedBox but you don't have to know if it's inside a Row or a Column. So that it's less verbose than using a SizedBox.

Getting started

In your library add the following import:

import 'package:gap/gap.dart';

Then you just have to add a Gap inside a Column or a Row with the specified extent.

return Column(
  children: <Widget>[
    Container(color: Colors.red, height: 20),
    const Gap(20), // Adds an empty space of 20 pixels.
    Container(color: Colors.red, height: 20),
  ],
);

The Gap widget also works inside Scrollable widgets such as ListViews. In these cases, it will occupy the space in the same direction as the Scrollable.

MaxGap

This package also comes with a MaxGap widget. The MaxGap widget will try to fill the available space in a Column or a Row with the specified size. If the available space is lesser than the specified size, the MaxGap widget will only take the available space.

It's useful when you want to have a gap that shrinks to avoid an overflow otherwise.

Other parameters

By default a Gap will have no extent in the opposite direction of the Flex parent. If you want the Gap to have a color, you'll have to set the color and the crossAxisExtent parameters. You can also use the Gap.expand constructor to expand the Gap in the opposite direction of the Flex parent.

SliverGap

There is also a Sliver version of the Gap widget:

return CustomScrollView(
  slivers: <Widget>[
    const SliverGap(20), // Adds an empty space of 20 pixels.
  ],
);

Changelog

Please see the Changelog page to know what's recently changed.

Contributions

Feel free to contribute to this project.

If you find a bug or want a feature, but don't know how to fix/implement it, please fill an issue.
If you fixed a bug or implemented a feature, please send a pull request.

gap's People

Contributors

bobagold avatar letsar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

gap's Issues

How to combine Gap with Expanded/Flexible widgets

Hello. I'm very familiar with the Expanded/Flexible widgets that help me a lot to position my widgets how I want in the Columns & Rows. But when I use them with Gap it doesn't seem to work as I would expect it.

Sample code

Column(
  children: [
    MaxGap(32),
    Text("Some title"),
    MaxGap(16),
    Text("Some subtitle"),
    Expanded(
      child: PageView(
        children: [
          CarouselSlide(),
          CarouselSlide(),
          CarouselSlide(),
        ],
      )
    ),
    MaxGap(24),
    TextButton(child: Text("A button")),
  ],
);

Expected outcome:

  1. The gaps between widgets don't exceed the value given to the MaxGap widget. While getting smaller if there is not enough space.
  2. The PageView (carousel in this example) expands and takes as much space as possible.

What I get:

For each MaxGap widget that I add the Expanded widget reduces its size to half.

How can I can use the Gap widget while still being able to utilize widgets like Expanded, Flexible or Spacer?

[Feature] Linter rule

I think it's possible to create custom linter rule in flutter.

Could be great to have a linter to avoid coding :
SizedBox(width:10) instead of Gap(10)
SizedBox(height:10) instead of Gap(10)

Proposal: Add `flex` parameter to `MaxGap`

It would be very useful to add a flex parameter to MaxGap. Sometimes it's necessary to combine several MaxGaps in one Column/Row. In this case they will be sharing flex 1 to 1. But sometimes you need to change that. Now it's only possible to do this, if you combine MaxGap with Spacer/Expanded/Flexible, which have built-in flex parameter.

Gap v3.0.0 breaks under Flutter 3.12.0-8.0.pre.21

In attempting to compile https://github.com/flutter/samples/tree/main/next_gen_ui_demo (and by extension https://github.com/flutter/codelabs/tree/main/next-gen-ui) under Flutter master channel, I'm seeing the following failures.

$ flutter run
Connected devices:
macOS (desktop) • macos  • darwin-arm64   • macOS 13.4 22F66 darwin-arm64
Chrome (web)    • chrome • web-javascript • Google Chrome 114.0.5735.133

No wireless devices were found.

[1]: macOS (macos)
[2]: Chrome (chrome)
Please choose one (or "q" to quit): 1
Launching lib/main.dart on macOS in debug mode...
2023-06-22 12:25:01.777 xcodebuild[68777:17538613] DVTCoreDeviceEnabledState: DVTCoreDeviceEnabledState_Disabled set via user default (DVTEnableCoreDevice=disabled)
--- xcodebuild: WARNING: Using the first of multiple matching destinations:
{ platform:macOS, arch:arm64, id:00006000-001250C00C38801E }
{ platform:macOS, arch:x86_64, id:00006000-001250C00C38801E }
../../../../.pub-cache/hosted/pub.dev/gap-3.0.0/lib/src/rendering/gap.dart:43:38: Error: A value of type 'RenderObject?' can't be assigned to a variable of type 'AbstractNode?'.
 - 'RenderObject' is from 'package:flutter/src/rendering/object.dart' ('../../../../flutter/packages/flutter/lib/src/rendering/object.dart').
 - 'AbstractNode' is from 'package:flutter/src/foundation/node.dart' ('../../../../flutter/packages/flutter/lib/src/foundation/node.dart').
    final AbstractNode? parentNode = parent;
                                     ^
../../../../.pub-cache/hosted/pub.dev/gap-3.0.0/lib/src/rendering/gap.dart:45:25: Error: The getter 'direction' isn't defined for the class 'AbstractNode?'.
 - 'AbstractNode' is from 'package:flutter/src/foundation/node.dart' ('../../../../flutter/packages/flutter/lib/src/foundation/node.dart').
Try correcting the name to the name of an existing getter, or defining a getter or field named 'direction'.
      return parentNode.direction;
                        ^^^^^^^^^
Target kernel_snapshot failed: Exception

Command PhaseScriptExecution failed with a nonzero exit code
warning: Run script build phase 'Run Script' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'Flutter Assemble' from project 'Runner')
** BUILD FAILED **

Building macOS application...                                           
Exception: Build process failed

I expect this version of Flutter to show up on the beta channel in the coming weeks, and show up in stable in August-ish.

For context, here's flutter doctor output:

$ flutter doctor -v
[✓] Flutter (Channel master, 3.12.0-8.0.pre.21, on macOS 13.4 22F66 darwin-arm64, locale en)
    • Flutter version 3.12.0-8.0.pre.21 on channel master at /Users/brettmorgan/flutter
    • Upstream repository https://github.com/flutter/flutter
    • Framework revision a2739c09a7 (31 minutes ago), 2023-06-22 06:01:18 -0400
    • Engine revision 8cc6d6d5ef
    • Dart version 3.1.0 (build 3.1.0-236.0.dev)
    • DevTools version 2.24.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/brettmorgan/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E300c
    • CocoaPods version 1.12.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)

[✓] IntelliJ IDEA Community Edition (version 2022.2.2)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 70.0.5
    • Dart plugin version 222.4167.21

[✓] VS Code (version 1.79.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.66.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.4 22F66 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 114.0.5735.133

[✓] Network resources
    • All expected network resources are available.

• No issues found!

How to use Gap in ListView's children?

How to use Gap in ListView's children?

Neither Gap nor SliverGap not seems works with ListView 🤔

ListView x Gap

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: const [
          Gap.expand(100, color: Colors.red),
        ],
      ),
    );
  }
I/flutter (12403): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (12403): The following assertion was thrown during performLayout():
I/flutter (12403): A Gap widget must be placed directly inside a Flex widget
I/flutter (12403): 
I/flutter (12403): The relevant error-causing widget was:
I/flutter (12403):   Gap file:///Users/mono/Git/gap/example/lib/main.dart:31:15
I/flutter (12403): 
I/flutter (12403): When the exception was thrown, this was the stack:
I/flutter (12403): #0      RenderGap.performLayout (package:gap/src/rendering/gap.dart:95:7)
I/flutter (12403): #1      RenderObject.layout (package:flutter/src/rendering/object.dart:1767:7)
I/flutter (12403): #2      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:13)
I/flutter (12403): #3      RenderObject.layout (package:flutter/src/rendering/object.dart:1767:7)
I/flutter (12403): #4      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:111:13)
I/flutter (12403): #5      RenderObject.layout (package:flutter/src/rendering/object.dart:1767:7)
I/flutter (12403): #6      RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:193:27)

ListView x SliverGap

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: const [
          SliverGap(100, color: Colors.red),
        ],
      ),
    );
  }
I/flutter (12403): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (12403): The following assertion was thrown building NotificationListener<KeepAliveNotification>:
I/flutter (12403): A RenderRepaintBoundary expected a child of type RenderBox but received a child of type
I/flutter (12403): RenderSliverGap.
I/flutter (12403): RenderObjects expect specific types of children because they coordinate with their children during
I/flutter (12403): layout and paint. For example, a RenderSliver cannot be the child of a RenderBox because a
I/flutter (12403): RenderSliver does not understand the RenderBox layout protocol.
I/flutter (12403): 
I/flutter (12403): The RenderRepaintBoundary that expected a RenderBox child was created by:
I/flutter (12403):   RepaintBoundary ← IndexedSemantics ← NotificationListener<KeepAliveNotification> ← KeepAlive ←
I/flutter (12403):   AutomaticKeepAlive ← KeyedSubtree ← SliverList ← MediaQuery ← SliverPadding ← Viewport ←
I/flutter (12403):   IgnorePointer-[GlobalKey#633e1] ← Semantics ← ⋯
I/flutter (12403): 
I/flutter (12403): The RenderSliverGap that did not match the expected child type was created by:
I/flutter (12403):   SliverGap ← RepaintBoundary ← IndexedSemantics ← NotificationListener<KeepAliveNotification> ←
I/flutter (12403):   KeepAlive ← AutomaticKeepAlive ← KeyedSubtree ← SliverList ← MediaQuery ← SliverPadding ← Viewport
I/flutter (12403):   ← IgnorePointer-[GlobalKey#633e1] ← ⋯
I/flutter (12403): 
I/flutter (12403): The relevant error-causing widget was:
I/flutter (12403):   ListView file:///Users/mono/Git/gap/example/lib/main.dart:29:13
I/flutter (12403): 
I/flutter (12403): When the exception was thrown, this was the stack:
I/flutter (12403): #0      RenderObjectWithChildMixin.debugValidateChild.<anonymous closure> (package:flutter/src/rendering/object.dart:2916:9)
I/flutter (12403): #1      RenderObjectWithChildMixin.debugValidateChild (package:flutter/src/rendering/object.dart:2943:6)
I/flutter (12403): #2      SingleChildRenderObjectElement.insertChildRenderObject (package:flutter/src/widgets/framework.dart:5848:25)

[Question] Compilation error with version 2.0.2

I have a compilation error with version 2.0.2 of gap.

Error: Member not found: 'Scrollable.maybeOf'.
    final scrollableState = Scrollable.maybeOf(context);
                                       ^^^^^^^
Error: Compilation failed.

The method Scrollable.maybeOf only exist after Flutter 3.7.x.

Can you use Scrollable.maybeOf in a version 3.0.0 which has set minimum Flutter version to 3.7.0 and revert the modification on gap 2.0.3 ?

Actually in production, our application use Flutter 3.3.x and since 3 days, our CI/CD couldn't compile for this reason.

`Gap` not working with `Wrap`

Is there something we can do to use Gap inside Wrap widget?

Wrap(
      direction: Axis.horizontal,
      crossAxisAlignment: WrapCrossAlignment.center,
      children: [
                Text(
                        'Message',
                        style: Get.textTheme.labelMedium!.copyWith(color: Colors.black.withOpacity(0.5)),
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                  ),
                  const Gap(5),
                  Icon(Icons.circle_rounded, size: 8 color: Colors.black.withOpacity(0.5)),
                  const Gap(5),
                  Text(message, style: Get.textTheme.labelMedium!.copyWith(color: Colors.black.withOpacity(0.5)))
       ]
)

Add `adaptive_breakpoints` Based `Gap` subclasses

I built the following package that is bscly a shittier version of Gap, except that it also provides Gap style classes that automatically size themselves according to adaptive_breakpoints so you don't have to specify the size manually:
https://pub.dev/packages/flutter_gutter

Honestly, this doesn't really need to be it's own package. It'd probably be way more useful to devs if this functionality were rolled into Gap. What do you think?

If you're for it, I'd be happy at making a first-pass PR to migrate my package's functionality into your package.

Add computeDryLayout

Hello!
In Flutter 1.25, there is a new method in RenderObject called computeDryLayout. It is used to calculate the size of the RenderObject by given constraints without the need to layout it.

image
https://flutter.dev/docs/release/breaking-changes/renderbox-dry-layout

As an example here is the implementation for RenderConstrainedBox used for SizedBox.

https://github.com/flutter/flutter/blob/4901744e62f67ad10440725d2c97e84e66ce77f5/packages/flutter/lib/src/rendering/proxy_box.dart#L288-L295

If you need, I would be happy to help with a PR

[Feature] A constructor optimized for empty widget ?

As a developer i want to use Gap to display an empty widget.

Previously for spacing i used many SizedBox() and Gap() successfully replace them.
But for empty spacing / widget, can we use Gap ? Is Gap as performance as SizedBox ? (Is Gap(0) a good practice ?)

  @override
  Widget build(BuildContext context) {
    if (enabled) return child;
    return const Gap(0); 
    // return const SizedBox(); 
  }

Add MinGap

Hello, great package!

I was thinking it would be nice to have a MinGap that works as the MaxGap but the opposite. It stretches in the main axis when there is space but can't be smaller than a given size.

This is helpful when you want to separate two Widgets in the main axis but if they don't have enough space they stay at a minimum distance. For example you want to have 2 buttons separated in a row but when the Row shrinks you want them to have a separation of at least 8px, because less than that the widgets would be too close together.

`flutter:master` FlutterError (Scrollable.of() was called with a context that does not contain a Scrollable widget.

The upcoming Flutter change from of to maybeOf might break gap: ^2.0.0, because of its usage of Scrollable.of.

Issue description

When using Gap(...) outside of a Scrollable container the issue will show up as:

Exception has occurred.
FlutterError (Scrollable.of() was called with a context that does not contain a Scrollable widget.
No Scrollable widget ancestor could be found starting from the context that was passed to Scrollable.of(). This can happen because you are using a widget that looks for a Scrollable ancestor, but no such ancestor exists.
The context used was:
  Gap(dirty))

A flutter version without the change will run without error.

What will/has change(d)

PR Add maybeOf for all the cases where of returns nullable has been merged to flutter:master and will most probably land in a beta and then stable release.

A description of the Flutter changes and a migration guide is available at:
Migrate of to non-nullable return values, and add maybeOf

Current Status 11/16/2022

gap: ^2.0.0 on current flutter:stable channel [Not reproduceable]

% flutter channel stable
% flutter upgrade 
% flutter --version
Flutter 3.3.8 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 52b3dc25f6 (7 days ago) • 2022-11-09 12:09:26 +0800
Engine • revision 857bd6b74c
Tools • Dart 2.18.4 • DevTools 2.15.0

gap: ^2.0.0 on flutter:beta channel [Not reproduceable]

% flutter channel beta
% flutter upgrade 
% flutter --version
Flutter 3.4.0-34.1.pre • channel beta • https://github.com/flutter/flutter.git
Framework • revision 71520442d4 (6 weeks ago) • 2022-10-05 16:38:28 -0500
Engine • revision db0cbb2145
Tools • Dart 2.19.0 (build 2.19.0-255.2.beta) • DevTools 2.18.0

gap: ^2.0.0 on flutter:master channel [Reproduceable]

% flutter channel master
% flutter upgrade 
% flutter --version
Flutter 3.6.0-3.0.pre.55 • channel master • https://github.com/flutter/flutter.git
Framework • revision 484e09ef79 (35 minutes ago) • 2022-11-16 05:18:10 -0500
Engine • revision 0241f18cbe
Tools • Dart 2.19.0 (build 2.19.0-406.0.dev) • DevTools 2.19.0

Quick fix for Flutter master / upcoming beta? channel users

I have made a change in my fork at fix_scrollable_of_issue_with_flutter_master

To use this fix, make the following change in your pubspec.yaml

  # gap: ^2.0.0
  gap: 
    git: 
      url: https://github.com/incima/gap.git
      ref: 307be282e99e6f27c2899cd5c81d724b267f18f4   

@letsar Thank you for this convenient package. This is just meant as a heads up.

Add SliverGap

Thanks for this package, it is really useful. I have been something similar to this but your implementation it is way better.

I would like to propose a SliverGap that would behave the same as Gap but for slivers.
Currently the simpler and cleaner way to add a gap between slivers is add a SliverPadding without a child.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.