简体   繁体   English

如何在 Flutter 中创建一个由多个选择器包装的可重用小部件

[英]How to create a reusable widget which is wrapped by multiple Selectors in Flutter

Is it possible to build a widget which can be reused and also listens to only one specific ChangeNotifier ?是否有可能构建一个可以重复使用的小部件并且只听一个特定的ChangeNotifier Let me explain with an example:让我用一个例子来解释:

I have 3 ChangeNotifier: NotifierA , NotifierB and NotifierC and I have a widget named MyLikeWidget which shows like count and all three ChangeNotifier contain a variable representing that like count.我有 3 个 ChangeNotifier: NotifierANotifierBNotifierC ,我有一个名为MyLikeWidget的小部件,它显示类似计数,所有三个 ChangeNotifier 都包含一个表示类似计数的变量。 If I want to reuse MyLikeWidget I can do this:如果我想重用MyLikeWidget ,我可以这样做:

 class ReusableWidget extends StatelessWidget {
   const ReusableWidget({Key? key, required this.changeNotifierType}) : super(key: key);
   final int changeNotifierType;

   @override
   Widget build(BuildContext context) {
     return changeNotifierType == 0 
        ? Selector<NotifierA, int>(
            selector: (c, notifierA) => notifierA.likeCount
            builder: (context, likeCount, child) => MyLikeWidget(likeCount: likeCount),
          )
        : changeNotifierType == 0
        ? Selector<NotifierB, int>(
            selector: (c, notifierB) => notifierB.likeCount
            builder: (context, likeCount, child) => MyLikeWidget(likeCount: likeCount),
          )
        : Selector<NotifierC, int>(
            selector: (c, notifierC) => notifierC.likeCount
            builder: (context, likeCount, child) => MyLikeWidget(likeCount: likeCount),
          );
   }
 }

class MyLikeWidget extends StatelessWidget {
  const MyLikeWidget({Key? key, required this.likeCount}) : super(key: key);
  final int likeCount;

  @override
  Widget build(BuildContext context) {
    return ComplexWidget(
      ....
    );
  }
}

The above approach can work if we have only a few reusable widgets and few ChnageNotfiers, but for large complex apps this approach will result in a lot of boilerplate code, we can solve this by using Selctor3 but this approach will rebuild MyLikeWidget every time like count changes in any ChangeNotifier this approach can create problems for complex reusable widgets like a reusable video widget which will rebuild even it is playing a video if the value it is listening to changes in any ChangeNotfier .如果我们只有几个可重用的小部件和几个 ChnageNotfiers,上面的方法可以工作,但是对于大型复杂的应用程序,这种方法会导致大量样板代码,我们可以通过使用 Selctor3 来解决这个问题,但是这种方法每次都会重建MyLikeWidget任何ChangeNotifier中的更改这种方法可能会给复杂的可重用小部件带来问题,例如可重用视频小部件,如果它正在侦听任何ChangeNotfier中的值发生变化,即使它正在播放视频也会重建。

Is there any other way we can approach this problem without writing a lot of boilerplate code?有没有其他方法可以在不编写大量样板代码的情况下解决这个问题?

Would this work - simply use the generics with your class:这行得通吗 - 只需将 generics 与您的 class 一起使用:

class ReusableWidget<T extends ChangeNotifierProvider> extends StatelessWidget {
   const ReusableWidget<T>({super.key});
   

   @override
   Widget build(BuildContext context) {
     return Selector<T, int>(
            selector: (c, notifierA) => notifierA.likeCount
            builder: (context, likeCount, child) => MyLikeWidget(likeCount: likeCount),
          );
   }
 }

And use it like this:并像这样使用它:

return ReusableWidget<NotifierA>(
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM