flutter_lid 1.2.1 copy "flutter_lid: ^1.2.1" to clipboard
flutter_lid: ^1.2.1 copied to clipboard

A Flutter library built to expose widgets that integrate with state notifier.

Lid #

Pub build codecov Star on GitHub License: MIT

A Flutter library built to expose widgets that integrate with state notifier. Built to work with the state_notifier state management packages.

It's very similar to widgets the bloc.

Motivation #

Already exists a package to integrate with the status notifier, called flutter_state_notifier, but flutter_lid covers different cases.

Usage #

Remember this package is destined to be used together with state_notifier

Let's take a look at how to use LidBuilder to hook up a CounterPage widget to a CounterState.

Add it in your pubspec.yaml:

dependencies:
  flutter_lid:
  state_notifier:

counter_lid.dart #

class CounterState extends StateNotifier<int> {
  CounterState() : super(0);

  void increment() => state += 1;

  void decrement() => state -= 1;
}

main.dart #

void main() => runApp(const LidCounter());

class LidCounter extends StatelessWidget {
  const LidCounter({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CounterPage(),
    );
  }
}

class CounterPage extends StatelessWidget {
  CounterPage({Key key}) : super(key: key);

  final _counter = CounterState();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Lid Counter')),
      body: LidBuilder<int>(
        stateNotifier: _counter,
        builder: (_, count) {
          return Center(
            child: Text(
              '$count',
              style: Theme.of(context).textTheme.headline1,
            ),
          );
        },
      ),
      floatingActionButton: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 4.0),
            child: FloatingActionButton(
              onPressed: _counter.increment,
              child: const Icon(Icons.add),
            ),
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 4.0),
            child: FloatingActionButton(
              onPressed: _counter.decrement,
              child: const Icon(Icons.remove),
            ),
          ),
        ],
      ),
    );
  }
}

Lid Widgets #

LidBuilder is a Flutter widget which requires a stateNotifier and a builder function. LidBuilder handles building the widget in response to new states. LidBuilder is very similar to StreamBuilder but has a more simple API to reduce the amount of boilerplate code needed. The builder function will potentially be called many times and should be a pure function that returns a widget in response to the state.

See LidListener if you want to "do" anything in response to state changes such as navigation, showing a dialog, etc...

LidBuilder<StateType>(
  stateNotifier: stateNotifier, // provide the state notifier instance
  builder: (context, state) {
    // return widget here based on State Notifier's state
  }
)

For fine-grained control over when the builder function is called buildWhen that can be provided that omitted, it will default true if previous stateis different currentstate, otherwise isfalse.buildWhentakes the previous state and current state and returns a boolean. IfbuildWhenreturns true,builderwill be called withstateand the widget will rebuild. IfbuildWhenreturns false,builderwill not be called withstate` and no rebuild will occur.

buildWhen is only called once for each state change (NOT including initialState).

LidBuilder<StateType>(
  stateNotifier: stateNotifier, // provide the state notifier instance
  buildWhen: (previousState, state) {
    // return true/false to determine whether or not
    // to rebuild the widget with state
  },
  builder: (context, state) {
    // return widget here based on State Notifier's state
  }
)

There is the possibility to animate between state changes.

LidBuilder<StateType>(
  stateNotifier: stateNotifier, // provide the state notifier instance
  animate: true, // Setting to `true`, fadeIn animation will be performed between widget changes.
  transitionBuilder: AnimatedSwitcher.defaultTransitionBuilder, // Here you can modify the default animation which is FadeIn.
  duration: Duration(milliseconds: 300), // Sets the duration of the animation.  
  builder: (context, state) {
    // return widget here based on State Notifier's state
  }
)

LidListener is a Flutter widget which takes a LidWidgetListener and requires a stateNotifier and invokes the listener in response to state changes in the state notifier. It should be used for functionality that needs to occur once per state change such as navigation, showing a SnackBar, showing a Dialog, etc...

listener is only called once for each state change (NOT including initialState) unlike builder in LidBuilder and is a void function.

LidListener<StateType>(
  stateNotifier: stateNotifier, // provide the state notifier instance
  listener: (context, state) {
    // do stuff here based on State Notifier's state
  },
  child: const SizedBox(),
)

For fine-grained control over when the listener function is called an optional listenWhen can be provided. listenWhen takes the previous state and current state and returns a boolean. If listenWhen returns true, listener will be called with state. If listenWhen returns false, listener will not be called with state.

LidListener<StateType>(
  stateNotifier: stateNotifier, // provide the state notifier instance
  listenWhen: (previousState, state) {
    // return true/false to determine whether or not
    // to call listener with state
  },
  listener: (context, state) {
    // do stuff here based on State Notifier's state
  },
  child: const SizedBox(),
)

MultiLidListener is a Flutter widget that merges multiple LidListener widgets into one. MultiLidListener improves the readability and eliminates the need to nest multiple LidListeners. By using MultiLidListener we can go from:

LidListener<StateType>(
  stateNotifier: stateNotifierA, // provide the state notifier instance
  listener: (context, state) {},
  child: LidListener<StateType>(
    stateNotifier: stateNotifierB, // provide the state notifier instance
    listener: (context, state) {},
    child: LidListener<StateType>(
      stateNotifier: stateNotifierC,// provide the state notifier instance
      listener: (context, state) {},
      child: ChildA(),
    ),
  ),
)

to:

MultiLidListener(
  listeners: [
    LidListener<StateType>(
      stateNotifier: stateNotifierA, // provide the state notifier instance
      listener: (context, state) {},
    ),
    LidListener<StateType>(
      stateNotifier: stateNotifierB, // provide the state notifier instance
      listener: (context, state) {},
    ),
    LidListener<StateType>(
      stateNotifier: stateNotifierC, // provide the state notifier instance
      listener: (context, state) {},
    ),
  ],
  child: ChildA(),
)

LidConsumer exposes a builder and listener in order react to new states. LidConsumer is analogous to a nested LidListener and LidBuilder but reduces the amount of boilerplate needed. LidConsumer should only be used when it is necessary to both rebuild UI and execute other reactions to state changes in the state notifier. LidConsumer takes a required LidWidgetBuilder and LidWidgetListener and StateNotifier, an optional LidBuilderCondition, and LidListenerCondition.

LidConsumer<StateType>(
  stateNotifier: stateNotifier, // provide the state notifier instance
  listener: (context, state) {
    // do stuff here based on State Notifier's state
  },
  builder: (context, state) {
    // return widget here based on State Notifier's state
  }
)

An optional listenWhen and buildWhen can be implemented for more granular control over when listener and builder are called. The listenWhen and buildWhen will be invoked on each state change. They each take the previous state and current state and must return a bool which determines whether or not the builder and/or listener function will be invoked. The previous state will be initialized to the state of the state_notifier when the LidConsumer is initialized. listenWhen and buildWhen are optional and if they aren't implemented, they will default to true.

If buildWhen é omitted then, it will default true if previous state is different current state, otherwise is false.

LidConsumer<StateType>(
  stateNotifier: stateNotifier, // provide the state notifier instance
  listenWhen: (previous, current) {
    // return true/false to determine whether or not
    // to invoke listener with state
  },
  listener: (context, state) {
    // do stuff here based on State Notifier's state
  },
  buildWhen: (previous, current) {
    // return true/false to determine whether or not
    // to rebuild the widget with state
  },
  builder: (context, state) {
    // return widget here based on State Notifier's state
  }
)

There is the possibility to animate between state changes.

LidConsumer<StateType>(
  stateNotifier: stateNotifier, // provide the state notifier instance
  animate: true, // Setting to `true`, fadeIn animation will be performed between widget changes.
  transitionBuilder: AnimatedSwitcher.defaultTransitionBuilder, // Here you can modify the default animation which is FadeIn.
  duration: Duration(milliseconds: 300), // Sets the duration of the animation.  
  listener: (context, state) {
    // do stuff here based on State Notifier's state
  },
  builder: (context, state) {
    // return widget here based on State Notifier's state
  }
)

LidSelector #

LidSelector is a Flutter widget which is analogous to LidBuilder but allows developers to filter updates by selecting a new value based on the current stateNotifier. Unnecessary builds are prevented if the selected value does not change. The selected value must be immutable in order for LidSelector to accurately determine whether builder should be called again.

LidSelector<StateType, SelectedState>(
  selector: (state) {
    // return selected state based on the provided state.
  },
  builder: (context, state) {
    // return widget here based on the selected state.
  },
)

There is the possibility to animate between state changes as LidBuilder.

Extensions #

There are 3 extensions for -> LidBuilder, LidListener and LidConsumer.

It's super simple to use:

// Same as LidBuilder
stateNotifier.toLidBuilder(  
  buildWhen: (previousState, state) {},
  builder: (context, state) {},
);

// Same as LidListener
stateNotifier.toLidListener(  
  listenWhen: (previousState, state) {},
  listener: (context, state) {},
  child: const SizedBox(),
);

// Same as LidConsumer
stateNotifier.toLidConsumer(
  listenWhen: (previous, current) {},
  listener: (context, state) {},
  buildWhen: (previous, current) {},
  builder: (context, state) {}
);

// Same as LidSelector
stateNotifier.toLidSelector<bool>(
  selector: (state) {},
  builder: (context, state) {},
),

Maintainers #

Support #

You liked this package? then give it a star. If you want to help then:

  • Fork this repository
  • Send a Pull Request with new features
  • Share this package
  • Create issues if you find a Bug or want to suggest something
5
likes
140
points
27
downloads

Publisher

verified publisherkmartins.dev

Weekly Downloads

A Flutter library built to expose widgets that integrate with state notifier.

Homepage
Repository (GitHub)
View/report issues

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, nested, state_notifier

More

Packages that depend on flutter_lid