Assorted Layout Widgets that boldly go Where no Native Flutter Widgets Have Gone Before

Assorted Layout Widgets that boldly go Where no Native Flutter Widgets Have Gone Before

Flutter package: Assorted layout widgets that boldly go where no native Flutter widgets have gone before.

assorted_layout_widgets

Widgets in this package:

  • ColumnSuper
  • RowSuper
  • FitHorizontally
  • Box
  • WrapSuper
  • TextOneLine

I will slowly but surely add interesting widgets to this package.

ColumnSuper

Given a list of children widgets, this will arrange them in a column. It can overlap cells, add separators and more.

ColumnSuper({  
    List<Widget> children,    
    double outerDistance,
    double innerDistance,
    bool invert,
    Alignment alignment,
    Widget separator,
    bool separatorOnTop,
  });

  • children is the list of widgets that represent the column cells, just like in a regular Column widget. However, the list may contain nulls, which will be ignored.

  • outerDistance is the distance in pixels before the first and after the last widget. It can be negative, in which case the cells will overflow the column.

  • innerDistance is the distance in pixels between the cells. It can be negative, in which case the cells will overlap.

  • invert if true will paint the cells that come later on top of the ones that came before. This is specially useful when cells overlap (negative innerDistance).

  • alignment will align the cells horizontally if they are smaller than the available horizontal space.

  • separator is a widget which will be put between each cells. Its height doesn't matter, since the distance between cells is given by innerDistance (in other words, separators don't occupy space). The separator will overflow if its width is larger than the column's width.

  • separatorOnTop if true (the default) will paint the separator on top of the cells. If false will paint the separator below the cells.

Note: This is not a substitute for Flutter's native Column, it doesn't try to have a similar API, and it doesn't do all that Column does. In special, Expanded and Flexible widgets don't work inside of ColumnSuper, and it will overflow if the column is not big enough to fit its contents. ColumnSuper is meant only for certain use cases where Column won't work, like when you need overlapping cells.

Try running the ColumnSuper example.

RowSuper

Given a list of children widgets, this will arrange them in a row. It can overlap cells, add separators and more.

RowSuper({  
    List<Widget> children,    
    double outerDistance,
    double innerDistance,
    bool invert,
    Alignment alignment,
    Widget separator,
    bool separatorOnTop,
    bool fitHorizontally,
    double shrinkLimit,
    MainAxisSize mainAxisSize,
  });

On contrary to ColumnSuper and the native Row (which will overflow if the cells are not big enough to fit their content), RowSuper will resize its cells, proportionately to the width of the minimum intrinsic width of each cell content.

Try running the RowSuper example.

Most parameters are the same as the ones of ColumnSuper, except:

  • fitHorizontally if true will resize the cells content, horizontally only, until the shrinkLimit is reached.

  • shrinkLimit by default is 67%, which means the cell contents will shrink until 67% of their original width, and then overflow. Make shrinkLimit equal to 0.0 if you want the cell contents to shrink with no limits. Note, if fitHorizontally is false, the shrinkLimit is not used.

  • mainAxisSize by default is MainAxisSize.min, which means the row will occupy no more than its content's width. Make it MainAxisSize.max to expand the row to occupy the whole horizontal space.

You can also use a RowSpacer to add empty space (if available) between cells. For example:

RowSuper(
   children: [
      widget1, 
      RowSpacer(), 
      widget2, 
      widget3,
      ]
   )
);   

Try running the RowSuper with FitHorizontally example.

Note: This is not a substitute for Flutter's native Row, it doesn't try to have a similar API, and it doesn't do all that Row does. In special, Expanded and Flexible widgets don't work inside of RowSuper, since RowSuper will resize cells proportionately when content doesn't fit. RowSuper is meant only for certain use cases where Row won't work, like when you need overlapping cells, or when you need to scale the contents of the cells when they don't fit.

FitHorizontally

FitHorizontally({
    Widget child,  
    double shrinkLimit,
    bool fitsHeight,
    AlignmentGeometry alignment,
  });

The child will be asked to define its own intrinsic height. If fitsHeight is true, the child will be proportionately resized (keeping its aspect ratio) to fit the available height.

Then, if the child doesn't fit the width, it will be shrinked horizontally only (not keeping its aspect ratio) until it fits, unless shrinkLimit is larger than zero, in which case it will shrink only until that limit. Note if shrinkLimit is 1.0 the child will not shrink at all. The default is 0.67 (67%).

This is specially useful for text that is displayed in a single line. When text doesn't fit the container it will shrink only horizontally, until it reaches the shrink limit. From that point on it will clip, display ellipsis or fade, according to the text's Text.overflow property.

Note: FitHorizontally with shrinkLimit 0.0 is not the same as FittedBox with BoxFit.fitWidth, because FitHorizontally will only scale horizontally, while FittedBox will maintain the aspect ratio.

Try running the FitHorizontally example.

Box

Box is something between a Container and a SizedBox, which is less verbose and can be made const.

const Box({
    bool show,
    Color color,
    double top,
    double right,
    double bottom,
    double left,
    double vertical,
    double horizontal,
    double width,
    double height,
    Alignment alignment,
    Widget child,
  });

Since it can be made const, it's good for creating colored boxes, with or without a child and padding:

const Box(color: Colors.red, width: 50, height:30);

The padding is given by top, right, bottom and left values, but they are only applied if the child is not null. If the child, width and height are all null, this means the box will occupy no space (will be hidden). Note: This will be extended in the future, so that it ignores horizontal padding when the child has zero width, and ignores vertical padding when the child has zero height.

If top and bottom are equal, you can instead provide vertical:

// This:
const Box(top: 20, bottom:20, child: ...);

// Is the same as this:
const Box(vertical: 20, child: ...);

You can't provide vertical and top or bottom at the same time.

Similarly, if right and left are equal, you can instead provide horizontal. You can't provide horizontal and right or left at the same time.

You can also hide the box by making the show parameter equal to false.

Clean-Code:

Box can be used as a cleaner substitute for Padding. For example, this code:

return Container(
    padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
    color: Colors.green,
    child: const Padding(
      padding: EdgeInsets.only(top: 12.0, bottom: 12.0, left: 4.0),      
      child: Text("Hello."),
    ),
  ),
);

Is the functional equivalent of this:

return const Box(
    vertical: 8.0,
    horizontal: 5.0,      
    color: Colors.green,
    child: Box(vertical: 12.0, left: 4.0, child: Text("Hello.")),
);

Debugging:

  • If need to quickly and temporarily add a color to your box so that you can see it, you can use the constructors Box.r for red, Box.g for green, Box.b for blue, and Box.y for yellow.

    Box(child: myChild);
    Box.r(child: myChild);
    Box.g(child: myChild);
    Box.b(child: myChild);
    Box.y(child: myChild);
  • If you want to see rebuilds, you can use the Box.rand constructor. It will then change its color to a random one, whenever its build method is called.

    Box.rand(child: myChild);  

WrapSuper

WrapSuper is similar to the native Wrap widget with direction = Axis.horizontal, but it allows you to choose different algorithms for the line-breaks.

WrapSuper displays its children in lines. It will leave spacing horizontal space between each child, and it will leave lineSpacing vertical space between each line. The contents of each line will then be aligned according to the alignment. The algorithm for the line-breaks is chosen by wrapType.

WrapSuper({
    Key key,
    WrapType wrapType,    
    double spacing,
    double lineSpacing,
    WrapSuperAlignment alignment,        
    List<Widget> children,
  });

WrapSuper with WrapType.fit uses a greedy algorithm for line breaks, which is the same one used by the native Wrap widget.

However, WrapSuper with WrapType.balanced (the default) uses a minimum raggedness algorithm for line breaks. It will position its child widgets in the same number of lines as the greedy algorithm, but these lines will tend to be more similar in width.

For example:

  • Here is my original StackOverflow question that resulted in this widget.

  • The algorithm I used was based on this one (Divide and Conquer), which always considers spacing: 1.0. It was changed (with the help of CodeChef) to allow for other spacings.

  • Add your thumbs up here if you want native Text widgets to also allow for better line-breaks.

TextOneLine

TextOneLine is a substitute for Text when maxLines: 1, to fix this issue: https://github.com/flutter/flutter/issues/18761 filled by myself a long time ago.

It uses a special fade-with-ellipsis, which is much better than the current buggy and ugly-looking ellipsis-that-cuts-the-whole-word.

For example, this:

Text("This isAVeryLongWordToDemonstrateAProblem", maxLines: 1, softWrap: false);  

Will print this in the screen:

This ...  

While this:

TextOneLine("This isAVeryLongWordToDemonstrateAProblem");  

Will print this:

This isAVeryLongWordToDemonst...  

This widget probably only makes sense while that issue is not fixed.

AlignPositioned

See package align_positioned for widgets AlignPositioned and its siblings AnimatedAlignPositioned and AnimChain. They should be part of this package, but will remain in their own package for historical reasons.

Download Details:

Author: marcglasberg

GitHub: https://github.com/marcglasberg/assorted_layout_widgets

flutter dart programming mobile-apps

What's new in Bootstrap 5 and when Bootstrap 5 release date?

How to Build Progressive Web Apps (PWA) using Angular 9

What is new features in Javascript ES2020 ECMAScript 2020

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Random Password Generator Online

HTML Color Picker online | HEX Color Picker | RGB Color Picker

ECommerce Mobile App Development | Ecommerce Mobile App Development Services

We are leading ecommerce mobile application development company. Hire our ecommerce mobile app developer for your custom Ecommerce project at competitive rates. **Know about [Top ECommerce Mobile App Development...

What will be the impact on your pocket if you opt for Flutter app development?

We cannot imagine the modern world without mobile apps as apps have become an integral part of our lifestyle. We have mobile apps for all our daily needs right from food to travel to medicines to movie or hotel bookings and many more. Mobile app development is indeed playing a prominent part in making the world fast-paced. Almost everything can be managed through mobile apps as they are rich in features and impeccable in making the life of user easy. The high performance of mobile apps has made it inevitable for businesses to opt for them or lag behind in …

Mobile App development Company in Melbourne Australia

If you are seeking online **[mobile app development Melbourne Australia](http://www.efrog.com.au/ "mobile app development Melbourne Australia")**? Then Efrog Pty Ltd is the best online choice for you we are an award-winning company in Australia....

Flutter for Beginners 2020 - Build a Flutter App with Google's Flutter & Dart

Free Flutter Introduction for Beginners: Get Started with Flutter and learn how to build an iOS and Android app with Flutter! Flutter Crash Course for Beginners 2020 - Build a Flutter App with Google's Flutter & Dart

Hire Dedicated Mobile App Development Company

AppClues Infotech is the best mobile app development company in New York that offers custom mobile app development & design services for Android and iOS.