StatelessWidget 中的 ScrollController

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

ScrollController 中使用

ListView
作为
StatelessWidget
是否
ok
?如果是的话,控制器该如何处置?

flutter dart
2个回答
4
投票

如果您使用

ScrollController
,我认为您的小部件中可能有一个状态(要更改或维护)。

在这种情况下,您需要去

StatefulWidget

我只需更改为

StatefulWidget
并使用
dispose()
方法来清理内存。

但首先,想想你的控制器是否有存在的目的。也许在你的情况下是有道理的。

也检查这个答案 --> 无状态小部件会自行处理吗?


0
投票

可以在无状态小部件中拥有此功能。为了保持我们的小部件无状态,我们使用 ControllerProvider。这是一个仅保存控制器的 Provider 类。它不会通知听众。这是 Provider 类:

class ControllerProvider {
  final List<ChangeNotifier> _controllers = [];

  T getController<T extends ChangeNotifier>({
    required T Function() create,
  }) {
    final controller = create();
    _controllers.add(controller);
    return controller;
  }

  void disposeAll() {
    for (var controller in _controllers) {
      print('${controller.toString()} disposed');
      controller.dispose();
    }
    _controllers.clear();
  }
}

在无状态小部件中,我们有以下方法:

  Widget _buildView(BuildContext context) {
    final controllerProvider = context.read<ControllerProvider>();

    _scrollController = controllerProvider.getController<ScrollController>(
      create: () => ScrollController(),
    );
    print('ScrollController ${_scrollController.toString()} created');
    _scrollController.addListener(() { // other code });

    // other code to return the widget UI

在我们的 Widget 构建方法中,我们将小部件包装在一个简单的 Provider 中,如下所示:

  Widget build(BuildContext context) {
    return ChangeNotifierProvider<SomeUIProvider>(
      create: (_) => SomeUIProvider()
        ..initializeProvider(errorCallback: (String message) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(content: Text(message)),
          );
        }),
      child: Provider<ControllerProvider>(
        create: (_) => ControllerProvider(),
        dispose: (_, controllerProvider) => controllerProvider.disposeAll(),
        child: Builder(builder: (context) => _buildView(context)),
      ),
    );
  }

每当我们需要使用像 TextEditingController 和 ScrollController 实例这样的控制器时,我们将小部件包装在这个 Provider 中,定义它的 dispose 方法。当此小部件离开导航堆栈或从导航堆栈中弹出时,由 ControllerProvider 管理的所有控制器都将被释放。

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