0

上下文:我将在我的应用程序中有几个可滚动的列表,并且我总是希望在添加项目时将它们滚动到最新的项目。

问题:我的 ListView.builders 和添加项目的地方在我的小部件树中相距甚远。通过构造函数传递所有这些滚动控制器似乎非常尴尬。

我的解决方案:当我目前正在使用 Provider 进行练习时,我想出了一个使用 Provider 的可行解决方案:

class ScrollControllerProvider with ChangeNotifier {
  ScrollController _paneController = ScrollController();
  //setting up all other controllers here later

  get paneController {
    return _paneController;
  }

  void scrollHistory() {
    WidgetsBinding.instance?.addPostFrameCallback((_) {
      if (_paneController.hasClients) {
        _paneController.jumpTo(_paneController.position.maxScrollExtent);
      }
    });
  }
}

我会将所有滚动控制器添加到该提供程序,并在我需要的地方获取我需要的内容。它已经适用于其中之一,但 reddit 上的某个人告诉我这不是一个好主意,因为应该处置滚动控制器。我对生命周期的话题还不是很了解,并且很难对此进行评估。

问题:在这里使用 Provider 真的是个坏主意吗?你能帮我理解为什么吗?如果是,解决此问题的最佳方法是什么?

4

2 回答 2

0

对于后代,Payam Asefi 为我指明了正确的方向。

我现在怎么样了。

tldr; Provider 包含一个可以切换的值和一个切换它的方法。我提供了我还可以访问滚动控制器的值。如果它被切换,则使用滚动控制器。我提供了在向列表中添加新项目时切换值的方法。

添加项目 > 触发提供程序中的值 > 侦听器意识到值已更改调用构建方法 > 滚动控制器用于转到 maxscrollextend。

带代码的长答案:

提供者 a) 可以切换的布尔值 b) 切换布尔值的方法 c) 布尔值的 getter

代码:

class ScrollControllerToggles with ChangeNotifier {
  bool _historyPaneSwitch = true;

  get getTogglePaneSwitch {
    return _historyPaneSwitch;
  }

  void toggleHistoryPane() {
    _historyPaneSwitch = !_historyPaneSwitch;
    notifyListeners();
  }
}

在小部件中,我使用 Listview.builder:a) 我定义了一个滚动控制器,b) 我使用了一个依赖于该 Provider 内的 _historyPaneSwitch 的函数。该函数还使用滚动控制器将列表滚动到末尾。

    void triggerScrollController() {
  bool scrollHistoryPane =
      Provider.of<ScrollControllerToggles>(context).getTogglePaneSwitch;
  WidgetsBinding.instance?.addPostFrameCallback((_) {
    if (paneController.hasClients) {
      paneController.jumpTo(paneController.position.maxScrollExtent);
    }
  });
}

在向列表添加新项目的小部件中,我再次访问提供程序并获取切换“_historyPaneSwitch”的方法。

    Function scrollHistoryPane =
    Provider.of<ScrollControllerToggles>(context).toggleHistoryPane;

    void dayChange(Function scrollHistoryPane) {
    mainElementList.insert(0, MainElement(false, DateTime.now().toString()));
    scrollHistoryPane;
  }
于 2022-02-13T22:45:21.293 回答
0

Provider不是问题,在提供者内部使用一次性物品是。ScrollController是与其主要相关的一次性物品Widget,或者更好的说法是其State

如果您想通知您的小部件有关新添加的项目,请在提供程序中创建一个变量并在您的小部件中侦听该变量,然后使用您ScrollController来更改位置。

要了解有关您的问题的更多信息,请查看ScrollController 类Disposable 类

于 2022-02-13T20:49:35.080 回答