如何最好地使我的滚动控制器在整个应用程序中可用?
How best to make my scroll controllers available throughout the app?
上下文:我的应用程序中将有几个可滚动的列表,我总是希望在添加项目时将它们滚动到最新的项目。
问题: 我的 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真的是个坏主意吗?你能帮我理解为什么吗?如果是,解决此问题的最佳方法是什么?
Provider
不是问题,在供应商内部使用一次性物品才是问题。 ScrollController
是与其主要 Widget
相关的一次性物品,或者更确切地说是其 State
.
如果您想通知您的小部件有关新添加的项目,请在提供程序中创建一个变量并在您的小部件中监听该变量,然后使用您的 ScrollController
更改位置。
要了解有关您的问题的更多信息,请查看 ScrollController class and Disposable class
为了后代,Payam Asefi 为我指明了正确的方向。
我现在做的怎么样。
tldr; 提供程序包含一个可以切换的值和一个切换它的方法。我提供了我还可以访问滚动控制器的值。如果它被切换,则使用滚动控制器。我提供了在向列表中添加新项目时切换值的方法。
添加项目 > 触发提供者中的值 > 侦听器意识到值已更改调用构建方法 > 滚动控制器用于转到 maxscrollextend。
带代码的长答案:
提供 a) 可以切换的 bool b) 切换 bool 的方法 c) bool 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;
}
上下文:我的应用程序中将有几个可滚动的列表,我总是希望在添加项目时将它们滚动到最新的项目。
问题: 我的 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真的是个坏主意吗?你能帮我理解为什么吗?如果是,解决此问题的最佳方法是什么?
Provider
不是问题,在供应商内部使用一次性物品才是问题。 ScrollController
是与其主要 Widget
相关的一次性物品,或者更确切地说是其 State
.
如果您想通知您的小部件有关新添加的项目,请在提供程序中创建一个变量并在您的小部件中监听该变量,然后使用您的 ScrollController
更改位置。
要了解有关您的问题的更多信息,请查看 ScrollController class and Disposable class
为了后代,Payam Asefi 为我指明了正确的方向。
我现在做的怎么样。
tldr; 提供程序包含一个可以切换的值和一个切换它的方法。我提供了我还可以访问滚动控制器的值。如果它被切换,则使用滚动控制器。我提供了在向列表中添加新项目时切换值的方法。
添加项目 > 触发提供者中的值 > 侦听器意识到值已更改调用构建方法 > 滚动控制器用于转到 maxscrollextend。
带代码的长答案:
提供 a) 可以切换的 bool b) 切换 bool 的方法 c) bool 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;
}