滚动初始阶段WebViewWidget底部闪烁条修复咨询(不替换NestedScrollView)
问题描述
滚动初始阶段,直到SliverAppBar缩小至最小尺寸时,WebViewWidget底部会出现闪烁条。因需同时访问外部和内部滚动,如何不替换NestedScrollView来修复该问题?
现有代码
SafeArea( child: Scaffold( body: NestedScrollView( //controller: controller, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ SliverOverlapAbsorber( handle: SliverOverlapAbsorberHandle(), sliver: SliverSafeArea( sliver: SliverAppBar( stretch: true, stretchTriggerOffset: 100, expandedHeight: 256, collapsedHeight: 56, pinned: true, ), ), ), ]; }, body: CustomScrollView( slivers: [ SliverToNestedScrollBoxAdapter( childExtent: 1491, onScrollOffsetChanged: (scrollOffset) { double y = scrollOffset; if (Platform.isAndroid) { y *= View.of(context).devicePixelRatio; } webViewController.scrollTo( 0, y.ceil()); }, child:WebViewWidget(controller: webViewController,) ), ], ),), ), ),
修复方案
以下几种方法可在保留NestedScrollView的前提下解决闪烁问题:
- 方法1:裁剪WebView并匹配精确高度
用ClipRect包裹WebViewWidget,同时确保SliverToNestedScrollBoxAdapter的childExtent与WebView实际内容高度完全一致,避免尺寸计算偏差引发的闪烁:
SliverToNestedScrollBoxAdapter( childExtent: 1491, // 必须和WebView实际内容高度精准匹配 onScrollOffsetChanged: (scrollOffset) { double y = scrollOffset; if (Platform.isAndroid) { y *= View.of(context).devicePixelRatio; } webViewController.scrollTo(0, y.ceil()); }, child: ClipRect( child: WebViewWidget(controller: webViewController), ), )
- 方法2:避开AppBar收缩阶段同步滚动
在滚动回调中判断SliverAppBar是否处于收缩过程,仅当AppBar完全收缩后再同步WebView滚动:
onScrollOffsetChanged: (scrollOffset) { // 计算当前AppBar的高度,判断是否已完成收缩 final appBarCurrentHeight = MediaQuery.of(context).padding.top + (scrollOffset < 256 - 56 ? 256 - scrollOffset : 56); if (appBarCurrentHeight <= 56) { double y = scrollOffset; if (Platform.isAndroid) { y *= View.of(context).devicePixelRatio; } webViewController.scrollTo(0, y.ceil()); } }
- 方法3:禁用WebView原生滚动
在WebView控制器配置中关闭原生滚动,完全依赖NestedScrollView控制滚动逻辑,消除双滚动源冲突:
final webViewController = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..loadRequest(Uri.parse("你的目标URL")) ..settings.apply(WebSettings( scrollEnabled: false, // 禁用WebView自身滚动 ));
内容的提问来源于stack exchange,提问作者Дмитрий Бобылев
相关产品推荐
相关产品推荐

