桌面上的預設捲軸
概述
#ScrollBehavior 現在會在桌面平臺(Mac、Windows 和 Linux)上自動為滾動控制元件應用 Scrollbar。
背景
#在此更改之前,Scrollbar 需要由開發者在所有平臺上手動應用於滾動控制元件。這與使用者在桌面平臺上執行 Flutter 應用程式時的預期不符。
現在,繼承的 ScrollBehavior 會自動將 Scrollbar 應用於大多數滾動控制元件。這類似於 ScrollBehavior 建立 GlowingOverscrollIndicator 的方式。少數豁免此行為的控制元件列在下方。
為了更好地管理和控制此功能,ScrollBehavior 也得到了更新。用於應用 GlowingOverscrollIndicator 的 buildViewportChrome 方法已被棄用。取而代之的是,ScrollBehavior 現在支援用於裝飾視口的獨立方法:buildScrollbar 和 buildOverscrollIndicator。可以覆蓋這些方法來控制滾動區域周圍的內容。
此外,ScrollBehavior 的子類 MaterialScrollBehavior 和 CupertinoScrollBehavior 已公開,允許開發者擴充套件和構建框架中其他現有的 ScrollBehavior。這些子類以前是私有的。
變更說明
#以前的方法要求開發者在所有平臺上建立自己的 Scrollbar。在某些用例中,需要將 ScrollController 提供給 Scrollbar 和滾動控制元件。
final ScrollController controller = ScrollController();
Scrollbar(
controller: controller,
child: ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
)
);ScrollBehavior 現在在桌面平臺上執行時會自動應用 Scrollbar,併為您處理將 ScrollController 提供給 Scrollbar 的操作。
final ScrollController controller = ScrollController();
ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
);框架中的一些控制元件豁免了此自動 Scrollbar 應用。它們是:
EditableText,當maxLines為 1 時。ListWheelScrollViewPageViewNestedScrollView
由於這些控制元件手動覆蓋了繼承的 ScrollBehavior 以移除 Scrollbar,因此所有這些控制元件現在都具有 scrollBehavior 引數,以便可以提供一個來代替覆蓋。
此更改在開發過程中沒有導致任何測試失敗、崩潰或錯誤訊息,但如果您正在桌面平臺上手動新增 Scrollbar,則可能會導致應用程式中渲染兩個 Scrollbar。
如果您在應用程式中看到此情況,有幾種方法可以控制和配置此功能。
在桌面執行時,從應用程式中移除手動應用的
Scrollbar。擴充套件
ScrollBehavior、MaterialScrollBehavior或CupertinoScrollBehavior來修改預設行為。- 有了您自己的
ScrollBehavior,您可以透過設定MaterialApp.scrollBehavior或CupertinoApp.scrollBehavior將其應用於整個應用程式。 - 或者,如果您只想將其應用於特定元件,請在相關元件上方新增一個
ScrollConfiguration,並使用您的自定義ScrollBehavior。
- 有了您自己的
您的滾動控制元件將繼承此設定並反映此行為。
- 與建立自己的
ScrollBehavior不同,更改預設行為的另一種選擇是複製現有的ScrollBehavior,然後切換所需的設定。- 在您的元件樹中建立一個
ScrollConfiguration,並使用copyWith提供當前上下文中現有ScrollBehavior的修改副本。
- 在您的元件樹中建立一個
遷移指南
#移除桌面上手動 Scrollbar
#遷移前的程式碼
final ScrollController controller = ScrollController();
Scrollbar(
controller: controller,
child: ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
)
);遷移後的程式碼
final ScrollController controller = ScrollController();
final Widget child = ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
);
// Only manually add a `Scrollbar` when not on desktop platforms.
// Or, see other migrations for changing `ScrollBehavior`.
switch (currentPlatform) {
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
return child;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.iOS:
return Scrollbar(
controller: controller,
child: child;
);
}為應用程式設定自定義 ScrollBehavior
#遷移前的程式碼
// MaterialApps previously had a private ScrollBehavior.
MaterialApp(
// ...
);遷移後的程式碼
// MaterialApps previously had a private ScrollBehavior.
// This is available to extend now.
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods like buildOverscrollIndicator and buildScrollbar
}
// ScrollBehavior can now be configured for an entire application.
MaterialApp(
scrollBehavior: MyCustomScrollBehavior(),
// ...
);為特定元件設定自定義 ScrollBehavior
#遷移前的程式碼
final ScrollController controller = ScrollController();
ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
);遷移後的程式碼
// MaterialApps previously had a private ScrollBehavior.
// This is available to extend now.
class MyCustomScrollBehavior extends MaterialScrollBehavior {
// Override behavior methods like buildOverscrollIndicator and buildScrollbar
}
// ScrollBehavior can be set for a specific widget.
final ScrollController controller = ScrollController();
ScrollConfiguration(
behavior: MyCustomScrollBehavior(),
child: ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
),
);複製並修改現有 ScrollBehavior
#遷移前的程式碼
final ScrollController controller = ScrollController();
ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
);遷移後的程式碼
// ScrollBehavior can be copied and adjusted.
final ScrollController controller = ScrollController();
ScrollConfiguration(
behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
child: ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Text('Item $index');
}
),
);時間線
#已登陸版本:2.2.0-10.0.pre
穩定版釋出:2.2.0
參考資料
#API 文件
ScrollConfigurationScrollBehaviorMaterialScrollBehaviorCupertinoScrollBehaviorScrollbarCupertinoScrollbar
相關問題
相關 PR