flutility 0.0.4
flutility: ^0.0.4 copied to clipboard
A collection of useful widgets and other stuff. All the widgets are documented. If you find any issues please report them at https://github.com/RoundedInfinity/flutility/issues.
Flutility #
A collection of useful widgets, material widgets that totally should be included in flutter and other stuff.
See how it works in the [examples](##How to use it)
See how to build a material selection effect in the Advanced Example
This package contains #
- SimpleAnimatedIcon
- Scale Item Switch
- Delayed Value Builder
- Delayed Value Stagger
- Logger
- Ripple Animation
Add the package to your pubspec.yaml
file.
flutility: <Newest Version>
And then import it.
import 'package:flutility/flutility.dart';
How to use it #
Bool controlled animation #
Most of the animated widget in this package are controlled with a bool
.
This makes simple animation a lot easier because you don't need a animation controller anymore.
Don't forget to call setState
after changing the value.
bool animate = false;
void animateSomething() {
setState(()) {
animate = !animate;
}}
Scale Item Switch #
A widget to switch between two icons with the simple material icon transition. Like the third transition here.
The animation is controlled by the [animate] value. [firstIcon] and [secondIcon] are properties in a IconButton
so they should be some sort of icon.
If [firstIcon] or [secondIcon] are not set the other icon will just disappear. Icons are in the disabled state if they don't have there VoidCallback set.
ScaleIconSwitch(
animate: animate,
firstIcon: Icon(Icons.delete_outline),
secondIcon: Icon(Icons.share_outlined),
onFirstPressed: switchIcon,
onSecondPressed: switchIcon,
)
Simple animated Icon #
Just use a bool
to control an animated icon.
And give it a Duration
if you want.
SimpleAnimatedIcon(
animate: animate,
icon: AnimatedIcons.play_pause,
);
Delayed Value Builder #
This widget updates a value
for his child after a delay
. Useful if you want to delay values for Foo animations.
Give the DelayedValueBuilder
a value. Then you can access the delayed value in the builder. When you call setState
the value
in the builder will be updated after the delay
.
DelayedValueBuilder(
builder: (context, value) => AnimatedContainer(
duration: Duration(milliseconds: 200),
color: value ? Colors.green : Colors.black,
height: 40,
width: 40,
),
value: animate,
delay: Duration(milliseconds: 700),
),
Delayed Value Stagger #
A ListView
that works like the delayed builder but has multiple widgets which are updated one after one.
DelayedValueStagger(
value: animate,
shrinkWrap: true,
duration: Duration(milliseconds: 200),
builder: (context, value) => [
Text('$value'),
Text('$value'),
Text('$value'),
Text('$value'),
],
),
Logger #
Tired of reading all these gray boring logs? Try Logger! Just create a logger somewhere in your code. You can give it a name if you want.
var logger = Logger(name: 'Logan the logger');
And now you can use it.
logger.log('Hello there');
Example App #
Example App that is using most of the features
show/hide
import 'package:flutter/material.dart';
import 'package:flutter_util/flutter_util.dart';
import 'app_bar_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
bool animate = false;
//Using the logger
void useLogger() {
Logger logger = Logger(name: 'Dieter the logger');
logger.log('Hello there!');
logger.logInfo('This is a info message');
var list = ['hello', 'there'];
logger.logRich(list, 'This is a rich message');
}
//Controlls the animation bool
void setAnimation() {
setState(() {
animate = !animate;
});
}
Widget _simpleAnimatedIcon() => SimpleAnimatedIcon(
animate: animate,
icon: AnimatedIcons.play_pause,
);
Widget _scaleItemSwitch() => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ScaleIconSwitch(
animate: animate,
firstIcon: Icon(Icons.share_outlined),
secondIcon: Icon(Icons.delete_outline),
// giving the icons a on pressed function so they are not in the disabled state.
onFirstPressed: () {},
onSecondPressed: () {},
),
//Just lets the icon disappear
ScaleIconSwitch(
animate: animate, duration: Duration(milliseconds: 500),
firstIcon: Icon(Icons.add_a_photo_outlined),
// giving the icons a on pressed function so they are not in the disabled state.
onFirstPressed: () {},
),
],
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('HomePage')),
body: Center(
child: Column(
children: [
RaisedButton(
onPressed: setAnimation,
child: Text('Animate it'),
),
Text('Simple animated icon'),
_simpleAnimatedIcon(),
Text('ScaleIconSwitch'),
_scaleItemSwitch(),
RaisedButton(
onPressed: useLogger,
child: Text('Hello logger'),
),
RaisedButton(
onPressed: () => Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => AppBarPage())),
child: Text('Advanced example'),
),
],
),
),
);
}
}
Advanced Example #
An App that uses the material design select effect
show/hide
import 'package:flutter/material.dart';
import 'package:flutter_util/flutter_util.dart';
class AppBarPage extends StatefulWidget {
@override
_AppBarPageState createState() => _AppBarPageState();
}
class _AppBarPageState extends State<AppBarPage> {
//We are using a logger here
Logger logger = Logger();
//If the item is selected animate will be set to true.
bool animate = false;
@override
Widget build(BuildContext context) {
Widget _appBar() => SliverAppBar(
pinned: true,
title: Text(
animate ? '1 item selected' : 'Advanced example',
style: TextStyle(color: animate ? Colors.white : Colors.black),
),
backgroundColor: Colors.white,
leading: Center(
child: IconButton(
onPressed: () {
setState(() {
if (animate) {
animate = false;
logger.log('Selection cancelled');
}
});
},
icon: SimpleAnimatedIcon(
animate: animate,
color: animate ? Colors.white : Colors.black,
icon: AnimatedIcons.menu_close,
),
),
),
actions: [
ScaleIconSwitch(
animate: animate,
secondIcon: Icon(
Icons.share_outlined,
color: Colors.white,
),
onSecondPressed: () => logger.log('Share!'),
),
ScaleIconSwitch(
animate: animate,
firstIcon: Icon(Icons.info_outline_rounded, color: Colors.black),
secondIcon: Icon(
Icons.delete_outline_outlined,
color: Colors.white,
),
onFirstPressed: () => logger.logInfo('Info!'),
onSecondPressed: () => logger.log('Delete!'),
),
],
//Put the RippleAnimation in the flexibleSpace
flexibleSpace: Container(
child: RippleAnimation(
animate: animate,
duration: Duration(milliseconds: 260),
// Offset so it looks like it starts at the bottom
offsetY: 90,
offsetX: 40,
rippleColor: Colors.deepPurpleAccent[400],
//If backgroundColor is not set it will be set transparent
height: 56,
),
),
);
return Scaffold(
backgroundColor: Colors.white,
body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) => [_appBar()],
body: Column(
children: [
CheckboxListTile(
activeColor: Colors.deepPurpleAccent[400],
value: animate,
controlAffinity: ListTileControlAffinity.leading,
title: Text('Something you can select'),
subtitle: Text('For a cool effect'),
onChanged: (bool value) {
setState(
() {
animate = value;
},
);
},
)
],
),
),
);
}
}