Flutter/Riverpod design question - how to pass riverpod 'final' function address to a complex UI widget?

47 views Asked by At

I have a Flutter UI that includes a very complex custom list/grid widget that I want to use in multiple different app situations.

For example, I have four different pages where I want to use this complex UI widget. Each of these four pages (e.g. Page1, Page2 etc) has their own RiverPod StateNotifierProvider (e.g. PageProvider1, PageProvider2 etc)

Inside the complex custom list/grid I want to:

  • Retrieve data from the provider to help minimize redrawing/repainting
  • Call provider notifier methods as responses to user interactions.

But the problem is how do I pass a reference to the custom list/grid about what RiverPod provider to call?

What I am trying to avoid is a set of 'switch' statements in the UI widget, like:

enum ProviderInUse {
   provider1,
   provider2,
   provider3,
   provider4
}

class CustomGridListWidget {

   ProviderInUse  _providerInUse;

   DataValue getData(int x, int y) {
      switch (_providerInUse) {
         case ProviderInUse.provider1:
            return ref.watch(Page1Provider.select.....);
         case ProviderInUse.provider2:
            return ref.watch(Page2Provider.select.....);
      }
   }

}

Any suggestions?

1

There are 1 answers

0
PurplePolyhedron On

provider can be passed to as regular parameter to your widget. Is there some reason you could not do this?

@riverpod
Color red(RedRef ref) => Colors.red;

@riverpod
Color blue(BlueRef ref) => Colors.blue;

class RiverBox extends ConsumerWidget {
  const RiverBox({super.key, required this.colorProvider});
  final ProviderBase<Color> colorProvider;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Container(
      color: ref.watch(colorProvider),
      height: 200,
      width: 200,
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});
  @override
  Widget build(BuildContext context) {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        RiverBox(colorProvider: redProvider),
        RiverBox(colorProvider: blueProvider),
      ],
    );
  }
}