在 Flutter 中设置相同值时,ValueListenableBuilder 不触发

问题描述 投票:0回答:1

在以下 Flutter 代码中,

ValueListenableBuilder
用于在
ValueNotifier
发生变化时显示对话框。但是,当再次设置相同的值时,不会触发该对话框。

ValueNotifier 仅在值发生变化时通知侦听器。目标是即使多次设置相同的值(true)也能触发对话框。

即使再次为 adWatchNeeded 设置相同的值(true),如何触发对话框?

让我们假设一个简单的视图模型类,如下所示,或者简单地尝试一下here

重要提示:不需要像 bloc、riverpod 等状态管理解决方案。

This is just for experimental purpose

class FeatureViewModel extends ChangeNotifier {
  ValueNotifier<bool> adWatchNeeded = ValueNotifier(false);

  void useFeature() {
    // Some API calls..
    // Unfortunately user must watch ads to use feature..
    adWatchNeeded.value = true;
  }
}

然后在UI端使用

  Widget _buildAdWatchNeededDialog() {
    return ValueListenableBuilder<bool>(
      valueListenable: _viewModel.adWatchNeeded,
      builder: (context, adWatchNeeded, child) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (adWatchNeeded) {
            showAdWatchNeededDiaog(context);
          }
        });
        return const SizedBox.shrink();
      },
    );
  }

然后在树上使用它

class SomeFeatureWidget extends StatefulWidget {
  const SomeFeatureWidget({Key? key}) : super(key: key);

  @override
  State<SomeFeatureWidget> createState() => _SomeFeatureWidgetState();
}

class _SomeFeatureWidgetState extends State<SomeFeatureWidget> {
  final _viewModel = FeatureViewModel();

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        _buildFeatureUsageDialog(),
        _buildAdWatchNeededDialog(),
      ],
    );
  }

  Widget _buildFeatureUsageDialog() {
    return TextButton(onPressed: () => _viewModel.useFeature(), child: const Text('Use Feature'));
  }

  Widget _buildAdWatchNeededDialog() {
    return ValueListenableBuilder<bool>(
      valueListenable: _viewModel.adWatchNeeded,
      builder: (context, adWatchNeeded, child) {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (adWatchNeeded) {
            showAdWatchNeededDiaog(context);
          }
        });
        return const SizedBox.shrink();
      },
    );
  }

  void showAdWatchNeededDiaog(BuildContext context) {
    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          content: const Text('Wath ads to use this feature'),
          actions: [
            TextButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: const Text('Watch Ad')),
            TextButton(
                onPressed: () {
                  Navigator.of(context).pop();
                },
                child: const Text('No, thanks'))
          ],
        );
      },
    );
  }
}
flutter flutter-change-notifier
1个回答
0
投票

ValueNotifier 仅在值发生变化时通知侦听器。目标是即使多次设置相同的值(true)也能触发对话框。

根据定义,这就是它应该如何工作。 如果即使值相同也需要事件,请考虑使用 Stream 的事件,或在值中包含微秒时间戳。

© www.soinside.com 2019 - 2024. All rights reserved.