flutter_plus 0.0.4
flutter_plus: ^0.0.4 copied to clipboard

Flutter Android iOS Linux macOS

Create customized Containers/Buttons/TextFields/Texts/RichTexts in a few lines. Navigate between Screens and open BottomSheets/Dialogs/Snackbars without context and more!

🌐 Languages: EN - PT

likes popularity pub points

πŸ—‚ Index #

πŸ‘Ύ FlutterPlus #

Creating apps using Flutter is great, but it can get better! #

FlutterPlus is an open-source library created to make Flutter development faster, easier and more intuitive.

Create Containers, Buttons, TextFields, Texts and RichTexts customized with few lines.

Navigate between Screens, open BottomSheets, Dialogs and Snackbars without context anywhere in your code.

Use extensions to treat dates, strings, numbers and files.

Many of the solutions found here were created for my own use throughout my journey with Flutter.

I decided to bring everything together in a single place to help my work and that of anyone interested. ;)

I will always try to keep the documentation up to date but it may happen that I forget to put something or other here.

🍬 Demonstration #

An appetizer of the real meaning of the library. Two codes that do the same thing, the first using the library and the second with native widgets.

A customized Container with centralized text that accepts user interaction.

FlutterPlus compare

πŸ”© Installation #

Add the flutter_plus dependency to your project's pubspec.yaml file.

dependencies:
  flutter_plus: any

Import a single file to access all components.

import 'package:flutter_plus/flutter_plus.dart';

- This library will always be in constant evolution, so:

1- If you don't want to have problems with names or attributes changing and stopping, I suggest setting the version when you start using it.

2- If you're like me who likes evolution and don't mind a little rework when it is for the best, leave it without a fixed version and stay tuned for updates ;)

*No extra adjustments are required to work on iOS, Android, Web or Desktop.

πŸ“š Examples #

The following are examples of how to use and configure the main features of the library.

*You can also find an example project showing how to use the library here.

πŸ›  Widgets #

The Widgets below are evolutions of the native Flutter. They were created to increase productivity and facilitate customization, with more powerful and intuitive attributes.

Create more complex widgets with less code.

πŸ“Œ ContainerPlus #

For me, the Container widget is the basis of Flutter. Our ContainerPlus is an evolution of the native, easier to customize and with several properties.

Example 1:

ContainerPlus(
  width: 150,
  height: 150,
  radius: RadiusPlus.all(20),
  color: Colors.yellow,
  shadows: [
    ShadowPlus(
      color: Colors.red,
      moveDown: -10,
      moveRight: -10,
      blur: 5,
      spread: 1,
      opacity: 0.2,
    ),
    ShadowPlus(
      color: Colors.blue,
      moveDown: 10,
      moveRight: 10,
      blur: 10,
      spread: 5,
      opacity: 0.5,
    ),
  ],
  border: BorderPlus(
    color: Colors.black,
    width: 2,
  ),
  child: TextPlus(
    'EXAMPLE 1',
    isCenter: true,
    color: Colors.white,
  ),
);

ContainerPlus example_1

Example 2:

ContainerPlus(
  margin: EdgeInsets.only(top: 48),
  width: 150,
  height: 150,
  isCircle: true,
  gradient: GradientPlus.linear(
    colors: [
      Colors.yellow,
      Colors.orange,
      Colors.pink,
    ],
    begin: Alignment.topLeft,
    end: Alignment.centerRight,
  ),
  innerShadows: [
    InnerShadowPlus(
      color: Colors.green,
      blur: 10,
    )
  ],
  child: TextPlus(
    'EXAMPLE 2',
    isCenter: true,
    color: Colors.white,
  ),
);

ContainerPlus example_2

Example 3:

bool isLoading = false;

ContainerPlus(
  margin: EdgeInsets.only(top: 48),
  width: 150,
  height: 150,
  color: Colors.black,
  radius: RadiusPlus.only(topLeft: 40, bottomRight: 10),
  skeleton: SkeletonPlus.automatic(enabled: this.isLoading),
  onTap: () {
    setState(() {
      this.isLoading = !this.isLoading;
    });
    Future.delayed(Duration(seconds: 5), () {
      setState(() {
        this.isLoading = !this.isLoading;
      });
    });
  },
  child: TextPlus(
    'EXAMPLE 3',
    isCenter: true,
    color: Colors.white,
  ),
);

ContainerPlus example_3

πŸ“Œ ButtonPlus #

Example 1:

ButtonPlus(
  width: 200,
  height: 60,
  radius: RadiusPlus.all(12),
  color: Colors.blue,
  enabled: true,
  splashColor: Colors.red,
  highlightColor: Colors.yellow,
  focusColor: Colors.green,
  hoverColor: Colors.pink,
  child: TextPlus(
    'EXAMPLE 1',
    color: Colors.white,
  ),
  onPressed: () {
    print('EXAMPLE 1');
  },
);

ButtonPlus example_1

Example 2:

ButtonPlus(
  margin: EdgeInsets.only(top: 48),
  width: 200,
  height: 60,
  radius: RadiusPlus.bottom(20),
  color: Colors.yellow,
  shadows: [
    ShadowPlus(
      color: Colors.red,
      moveDown: -10,
      moveRight: -10,
      blur: 5,
      spread: 1,
      opacity: 0.2,
    ),
    ShadowPlus(
      color: Colors.blue,
      moveDown: 10,
      moveRight: 10,
      blur: 10,
      spread: 5,
      opacity: 0.5,
    ),
  ],
  border: BorderPlus(
    color: Colors.black,
    width: 2,
  ),
  child: TextPlus(
    'EXAMPLE 2',
    color: Colors.white,
  ),
  onPressed: () {
    print('EXAMPLE 2');
  },
);

ButtonPlus example_2

Example 3:

ButtonPlus(
  margin: EdgeInsets.only(top: 48),
  width: 200,
  height: 60,
  isCircle: true,
  gradient: GradientPlus.linear(
    colors: [
      Colors.yellow,
      Colors.orange,
      Colors.pink,
    ],
    begin: Alignment.topLeft,
    end: Alignment.centerRight,
  ),
  innerShadows: [
    InnerShadowPlus(
      color: Colors.green,
      blur: 10,
    )
  ],
  child: TextPlus(
    'EXAMPLE 3',
    color: Colors.white,
  ),
  onPressed: () {
    print('EXAMPLE 3');
  },
);

ButtonPlus example_3

Example 4:

bool isLoading = false;

ButtonPlus(
  margin: EdgeInsets.only(top: 48),
  width: 200,
  height: 60,
  color: Colors.black,
  radius: RadiusPlus.only(topLeft: 40, bottomRight: 10),
  skeleton: SkeletonPlus.automatic(enabled: this.isLoading),
  child: TextPlus(
    'EXAMPLE 4',
    color: Colors.white,
  ),
  onPressed: () {
    print('EXAMPLE 4');

    setState(() {
      this.isLoading = !this.isLoading;
    });
    Future.delayed(Duration(seconds: 5), () {
      setState(() {
        this.isLoading = !this.isLoading;
      });
    });
  },
);

ButtonPlus example_4

πŸ“Œ TextFieldPlus #

Example 1:

TextFieldPlus(
  padding: EdgeInsets.symmetric(horizontal: 8),
  height: 60,
  backgroundColor: Colors.black12,
  cursorColor: Colors.red,
  enabled: true,
  textInputType: TextInputType.emailAddress,
  placeholder: TextPlus(
    'E-mail',
    color: Colors.black38,
  ),
  prefixWidget: Icon(
    Icons.alternate_email,
    color: Colors.redAccent,
  ),
  suffixWidget: Icon(
    Icons.email,
    color: Colors.redAccent,
  ),
);

TextFieldPlus example_1

Example 2:

TextFieldPlus(
  margin: EdgeInsets.only(top: 24),
  padding: EdgeInsets.symmetric(horizontal: 8),
  height: 60,
  backgroundColor: Colors.black12,
  cursorColor: Colors.red,
  textInputType: TextInputType.number,
  mask: '###.###.###-##',
  placeholder: TextPlus(
    'CPF',
    color: Colors.black38,
  ),
);

TextFieldPlus example_2

Example 3:

TextFieldPlus(
  margin: EdgeInsets.only(top: 24),
  padding: EdgeInsets.symmetric(horizontal: 8),
  height: 60,
  cursorColor: Colors.white,
  textCapitalization: TextCapitalization.words,
  maxLines: 1,
  letterSpacing: 2,
  gradient: GradientPlus.linear(
    colors: [
      Colors.red,
      Colors.orange,
      Colors.yellow,
    ],
  ),
  radius: RadiusPlus.all(12),
  placeholder: TextPlus(
    'Name',
    color: Colors.white70,
  ),
  suffixWidget: Icon(
    Icons.person,
    color: Colors.white70,
  ),
  textColor: Colors.white,
  fontSize: 16,
  fontWeight: FontWeight.bold,
);

TextFieldPlus example_3

πŸ“Œ TextPlus #

Example 1:

TextPlus(
  'Exemplo 1',
  padding: EdgeInsets.all(16),
  backgroundColor: Colors.red,
  color: Colors.white,
  fontSize: 20,
  fontWeight: FontWeight.w700,
  letterSpacing: 2,
  wordSpacing: 20,
  maxLines: 1,
  textOverflow: TextOverflow.ellipsis,
);

TextPlus example_1

Example 2:

TextPlus(
  'Exemplo 2',
  color: Colors.white,
  fontSize: 20,
  margin: EdgeInsets.only(top: 24),
  padding: EdgeInsets.all(16),
  backgroundGradient: GradientPlus.linear(
    colors: [
      Colors.yellow,
      Colors.orange,
      Colors.pink,
    ],
    begin: Alignment.topLeft,
    end: Alignment.centerRight,
  ),
  backgroundRadius: RadiusPlus.all(10),
  backgroundBorder: BorderPlus(
    color: Colors.blue,
    width: 2,
  ),
  textShadows: [
    ShadowPlus(
      color: Colors.black45,
      blur: 10,
    )
  ],
);

TextPlus example_2

Example 3:

TextPlus(
  '00000000000',
  margin: EdgeInsets.only(top: 24),
  padding: EdgeInsets.all(16),
  backgroundColor: Colors.black,
  color: Colors.white,
  fontSize: 20,
  mask: '###.###.###-##',
  onTap: () {
    print('Exemplo 3');
  },
);

TextPlus example_3

πŸ“Œ RichTextPlus #

RichTextPlus(
  texts: [
    TextPlus(
      'Flutter ',
      color: Colors.black,
      fontWeight: FontWeight.normal,
      fontSize: 30,
    ),
    TextPlus(
      'Plus ',
      color: Colors.red,
      fontWeight: FontWeight.bold,
      fontSize: 30,
    ),
    TextPlus(
      '!',
      color: Colors.blue,
      fontWeight: FontWeight.bold,
      fontSize: 30,
    ),
    TextPlus(
      '!',
      color: Colors.green,
      fontWeight: FontWeight.bold,
      fontSize: 30,
    ),
    TextPlus(
      '!',
      color: Colors.orange,
      fontWeight: FontWeight.bold,
      fontSize: 30,
    ),
  ],
);

RichTextPlus example

πŸ”§ Utils #

In addition to the standard widgets we have some abstractions that will save you code and time so you can focus on what really matters to your project.

πŸ“Œ NavigatorPlus #

NavigatorPlus makes it possible to navigate between screens from anywhere in your code, without the need for a context.

You need to configure it to work.

β€’ Navigate to the next screen:

// Navigate to desired screen
navigatorPlus.show(NextScreen());
// Open desired screen as modal
navigatorPlus.showModal(NextScreen());

β€’ Back or close screen:

// Back or close to previous screen
navigatorPlus.back();
// Check if there is a previous screen to go back
if (navigatorPlus.canBack) {
  navigatorPlus.back();
}
// Back to first stack screen
navigatorPlus.backAll();

β€’ Return data to source screen:

// Call the next screen with await waiting for a return
var result = await navigatorPlus.show(NextScreen());

// Return to the previous screen passing the desired data
navigatorPlus.back(result: customData);

β€’ Configuration:

Recommended: Replace MaterialApp with FlutterAppPlus.

return FlutterAppPlus(
  title: 'Flutter Plus Example',
  home: HomeScreen(),
);

Alternative: Add the keys of the navigatorPlus and snackBarPlus.

MaterialApp(
  title: 'Flutter Plus Example',
  navigatorKey: navigatorPlus.key,
  builder: (context, child) {
    return Scaffold(
      key: snackBarPlus.scaffoldKey,
      body: child,
    );
  },
);

β€’ Context:

// Get current context
BuildContext context = navigatorPlus.currentContext;

β€’ Access:

navigatorPlus.show(NextScreen());

FlutterPlus.navigator.show(NextScreen());

πŸ“Œ BottomSheetPlus #

O BottomSheetPlus possibilita a abertura em qualquer lugar do seu cΓ³digo, sem a necessidade de um context.

You need to configure it to work.

bottomSheetPlus.show(
  child: CustomWidget(),
  radius: RadiusPlus.top(20),
  heightPercentScreen: 0.3,
);

BottomSheetPlus example

β€’ Access:

bottomSheetPlus.show(...);

FlutterPlus.bottomSheet.show(...);

β€’ Configuration:

Recommended: Replace MaterialApp with FlutterAppPlus.

return FlutterAppPlus(
  title: 'Flutter Plus Example',
  home: HomeScreen(),
);

Alternative: Add the keys of the navigatorPlus and snackBarPlus.

MaterialApp(
  title: 'Flutter Plus Example',
  navigatorKey: navigatorPlus.key,
  builder: (context, child) {
    return Scaffold(
      key: snackBarPlus.scaffoldKey,
      body: child,
    );
  },
);

πŸ“Œ DialogPlus #

DialogPlus makes it possible to open a dialog with an already defined layout.

You need to configure it to work.

// Opening of customizable default Dialog

const url = 'https://github.com/gbmiranda/flutter_plus';

dialogPlus.showDefault(
	title: 'FlutterPlus',
	message: url,
	elementsSpacing: 16,
	buttonOneText: 'Close',
	buttonOneColor: Colors.red,
	buttonOneCallback: () {
	  navigatorPlus.back();
	},
	buttonTwoText: 'Open',
	buttonTwoCallback: () async {
	  if (await canLaunch(url)) {
	    await launch(url);
	  } else {
	    throw 'Could not launch $url';
	  }
	},
);

DialogPlus example

// Dialog opening with its own layout

  dialogPlus.show(
    child: CustomWidget(),
    radius: RadiusPlus.all(20),
    closeKeyboardWhenOpen: true,
  );

DialogPlus example

β€’ Access:

dialogPlus.show(...);

FlutterPlus.dialog.show(...);

β€’ Configuration:

Recommended: Replace MaterialApp with FlutterAppPlus.

return FlutterAppPlus(
  title: 'Flutter Plus Example',
  home: HomeScreen(),
);

Alternative: Add the keys of the navigatorPlus and snackBarPlus.

MaterialApp(
  title: 'Flutter Plus Example',
  navigatorKey: navigatorPlus.key,
  builder: (context, child) {
    return Scaffold(
      key: snackBarPlus.scaffoldKey,
      body: child,
    );
  },
);

πŸ“Œ SnackBarPlus #

SnackBarPlus allows you to open your code anywhere, without the need for a scaffold.

You need to configure it to work.

// SnackBar opening with plain text

snackBarPlus.showText(
  'FlutterPlus',
  textColor: Colors.white,
  fontSize: 18,
  fontWeight: FontWeight.bold,
  backgroundColor: Colors.green,
);

SnackBarPlus example

// SnackBar opening with custom widget

snackBarPlus.show(
	backgroundColor: Colors.green,
	child: Row(
	  mainAxisAlignment: MainAxisAlignment.center,
	  children: [
	    Icon(
	      Icons.star,
	      color: Colors.yellow,
	    ),
	    SizedBox(
	      width: 8,
	    ),
	    TextPlus(
	      'FlutterPlus!',
	      color: Colors.white,
	      fontSize: 18,
	      fontWeight: FontWeight.bold,
	    ),
	    SizedBox(
	      width: 8,
	    ),
	    Icon(
	      Icons.star,
	      color: Colors.yellow,
	    ),
	  ],
	),
);

SnackBarPlus example

β€’ Configuration:

Recommended: Replace MaterialApp with FlutterAppPlus.

return FlutterAppPlus(
  title: 'Flutter Plus Example',
  home: HomeScreen(),
);

Alternative: Add the keys of the navigatorPlus and snackBarPlus.

MaterialApp(
  title: 'Flutter Plus Example',
  navigatorKey: navigatorPlus.key,
  builder: (context, child) {
    return Scaffold(
      key: snackBarPlus.scaffoldKey,
      body: child,
    );
  },
);

β€’ Access:

snackBarPlus.show(...);

FlutterPlus.snackBar.show(...);

πŸ“Œ LocalStoragePlus #

LocalStoragePlus makes it possible to persist and access local data anywhere in your code.

// Save local data
await localStoragePlus.write('lib_name', 'flutter_plus');

// Read local data
await localStoragePlus.read('lib_name');

// Erase local data
await localStoragePlus.delete('lib_name');

// Check for local data
await localStoragePlus.containsKey('lib_name');

// Clear all local data
await localStoragePlus.clear();

β€’ Access:

localStoragePlus...;

FlutterPlus.localStorage...;

Uses the shared_preferences dependency.

πŸ“Œ UtilsPlus #

UtilsPlus provides functions to assist in the development of your application.

// Close the keyboard if it is open
utilsPlus.closeKeyboard();

// Get a Color from a Hex
Color customColor = utilsPlus.colorHex('FFFFFF');

β€’ Access:

utilsPlus...;

FlutterPlus.utils...;

🧩 ExtensionsPlus #

Last but not least, *** Extensions *** are a powerful tool to make certain tasks easier without having to replicate code multiple times.

In this section you will find various extensions for the types String, Date, Num, File, Duration.

Sometimes it is difficult to keep everything up to date, so new properties may appear that are not here.

πŸ“Œ StringExtensionPlus #

β€’ Properties:

PropertyExampleResult
toDate"11/08/1992".toDate(format: "dd/MM/yyyy");DateTime
capitalizeFirstWord"flutter plus".capitalizeFirstWord;Flutter plus
capitalizeAllWords"flutter plus".capitalizeAllWords;Flutter Plus
setMask"00000000000".setMask(mask: "###.###.###-##");000.000.000-00
cleanDiacritics ou removerAcentos"fluttΓ©r plΓΊs". cleanDiacritics;flutter plus
firstLetter"flutter plus".firstLetter;f
firstWord"flutter plus".firstWord;flutter
toBase64"flutter plus".toBase64;base64Str
fromBase64base64Str.fromBase64;flutter plus
cleanString"* flutter plus *".cleanString;flutter plus
cleanStringAndSpaces"* flutter plus *".cleanStringAndSpaces;flutterplus
isNotNullOrEmpty"flutter plus".isNotNullOrEmpty;true
isEmail"flutter plus".isEmail;false
isNum"flutter plus".isNum;false
isBool"flutter plus".isBool;false
isDateTime"flutter plus".isDateTime;false
isURL"flutter plus".isURL;false
isCpf"flutter plus".isCpf;false
isCelular"flutter plus".isCelular;false
isTelefone"flutter plus".isTelefone;false

β€’ Example:

String dateStr = "01/01/2020 10:00:00";
DateTime date = dateStr.toDate("dd/MM/yyyy");
print(date.year); 
// 2020

πŸ“Œ DateExtensionPlus #

β€’ Properties:

PropertyReturn TypeResult
formatStringString with formatted date
daysOfMonthintNumber of days of the month
daysOfYearintNumber of days in the year (366 when binary year)
isTodayboolTrue or false
monthNameStringMonth name
monthNameSortStringSummarized month name
weekNameStringDay of the week
weekNameSortStringSummary day of the week

β€’ Example:

DateTime.now date = DateTime.now();
String dateStr = date.format("dd/MM/yyyy");
print(dateStr); 
// 01/01/2020

πŸ“Œ NumExtensionPlus #

β€’ Properties:

PropertyReturn TypeResult
toCurrencyStringFormats to local currency
toCurrencyCompactStringFormats to summarized local currency
toPrecisiondoubleSets number of decimal places
daysToHoursintDays to hours
minutesToHoursintMinutes to hours
secondsToHoursintSeconds to hours
hoursToDaysintHours to days
secondsToMinutesintSeconds to minutes
hoursToMinutesintHours to minutes
isNullOrZeroboolChecks if it is different from null or zero

β€’ Example:

double value = 13512.98;
print(value.toCurrency()); 
// $ 13,512.98
// R$ 13.512,98

πŸ“Œ FileExtensionPlus #

β€’ Properties:

PropertyReturn TypeResult
base64SyncStringConverts to base64 sync
base64AsyncStringConverts to base64 async

β€’ Example:

File customFile = File(path);
String base64 = customFile.base64Sync;

πŸ“Œ DurationExtensionPlus #

β€’ Properties:

PropertyReturn TypeResult
monthsintReturns the number of months of Duration
daysintReturns the number of days of Duration
hoursintReturns the number of hours of Duration
hoursStrStringReturns the formatted number of hours of Duration
minutesintReturns the number of minutes of Duration
minutesStrStringReturns the formatted number of minutes of Duration
secondsintReturns the number of seconds of Duration
secondsStrStringReturns the formatted number of seconds of Duration
formattedDurationStringReturns the formatted Duration

β€’ Example:

Duration customDuration = Duration(hours: 10, minutes: 4, seconds: 55);
print(customDuration.days); // 0
print(customDuration.hours); // 10
print(customDuration.minutesStr); // 04
print(customDuration.formattedDuration); // 10:04:55

βš™οΈ Attributes #

The customization attributes below are used in most of the widgets above.

πŸ“Œ BorderPlus #

BorderPlus(
  color: Colors.black,
  style: BorderStyle.solid,
  width: 2.0,
);

πŸ“Œ GradientPlus #

GradientPlus.linear(
  colors: [Colors.black, Colors.white],
  begin: Alignment.centerLeft,
  end: Alignment.centerRight,
  stops: [0.2, 0.8],
);
GradientPlus.radial(
  colors: [Colors.black, Colors.white],
  center: Alignment.centerLeft,
  focal: Alignment.bottomCenter,
  focalRadius: 1.5,
  radius: 4.5,
  stops: [0.3, 0.7],
);
GradientPlus.sweep(
  colors: [Colors.black, Colors.white],
  center: Alignment.centerLeft,
  startAngle: 1.5,
  endAngle: 3.2,
  stops: [0.5, 0.8],
);

πŸ“Œ InnerShadowPlus #

InnerShadowPlus(
  color: Colors.red,
  blur: 10.0,
  moveDown: 4.5,
  moveRight: 2.5,
  opacity: 0.5,
);

πŸ“Œ RadiusPlus #

RadiusPlus.all(12.0);
RadiusPlus.bottom(12.0);
RadiusPlus.top(12.0);
RadiusPlus.only(
  topLeft: 10.0,
  topRight: 16.0,
  bottomLeft: 4.0,
  bottomRight: 8.0,
);

πŸ“Œ ShadowPlus #

ShadowPlus(
  color: Colors.red,
  blur: 10.0,
  spread: 2.5,
  moveDown: 4.5,
  moveRight: 2.5,
  opacity: 0.5,
);

πŸ“Œ SkeletonPlus #

bool isLoading = true;
SkeletonPlus.automatic(enabled: isLoading);
bool isLoading = true;
SkeletonPlus.custom(
  enabled: isLoading,
  baseColor: Colors.black87,
  highlightColor: Colors.black26,
  duration: Duration(
    milliseconds: 500,
  ),
  showBorders: false,
  showShadows: false,
);

πŸ“Œ TextDecorationPlus #

TextDecorationPlus(
  color: Colors.red,
  decorationStyle: TextDecorationStyle.dashed,
  decorationThickness: 0.5,
);

🎯 Next Steps #

πŸ“Œ Detailed documentation of the components.

πŸ“Œ Route Navigation

πŸ“Œ ScaffoldPlus.

πŸ“Œ GridViewPlus.

πŸ“Œ ListViewPlus.

πŸ“Œ LoadingPlus.

πŸ“Œ ThemePlus.

πŸ“Œ TranslatePlus.

πŸ“Œ ∞

18
likes
70
pub points
61%
popularity

Create customized Containers/Buttons/TextFields/Texts/RichTexts in a few lines. Navigate between Screens and open BottomSheets/Dialogs/Snackbars without context and more!

Repository (GitHub)
View/report issues

Documentation

API reference

Uploader

gbmiranda92@gmail.com

License

MIT (LICENSE)

Dependencies

diacritic, flutter, intl, path, shared_preferences

More

Packages that depend on flutter_plus