Могу ли я использовать webview_flutter в CustomScrollView и ленту для анимации панели приложения
Я пытаюсь создать экран с WebView (из webview_flutter: ^0.2.0) и панелью приложений, которую я хочу прокручивать за пределами экрана при пользовательской прокрутке. Я наткнулся на этот https://flutterdoc.com/animating-app-bars-in-flutter-cf034cd6c68b и попытался реализовать нечто подобное, но без кубиков. Есть ли способ использовать WebView в CustomScrollView со Slivers или это еще не поддерживается?
Я могу заставить работать панель прокрутки, если создаю обычные виджеты в моем SliverChildListDelegate (я пробовал Row, Text, Container и т. Д.), Но мне не повезло с WebView. Вот метод сборки (извините за странное форматирование, редактор вопросов испортил его).
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: const Text("Heading"),
floating: true,
),
SliverList(
delegate: SliverChildListDelegate([
Container(
child: WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
),
)
]
),
)
],
)
);
}
Я получаю следующий стек с этим кодом:
I/flutter (20859): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (20859): The following assertion was thrown during performLayout():
I/flutter (20859): 'package:flutter/src/rendering/object.dart': Failed assertion: line 1578 pos 12:
I/flutter (20859): '!_debugDoingThisLayout': is not true.
I/flutter (20859):
I/flutter (20859): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (20859): more information in this error message to help you determine and fix the underlying cause.
I/flutter (20859): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (20859): https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (20859):
I/flutter (20859): When the exception was thrown, this was the stack:
I/flutter (20859): #2 RenderObject.layout (package:flutter/src/rendering/object.dart:1578:12)
I/flutter (20859): #3 RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:164:27)
I/flutter (20859): #4 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #5 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:405:13)
I/flutter (20859): #6 RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1316:12)
I/flutter (20859): #7 RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1234:20)
I/flutter (20859): #8 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #9 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #10 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #11 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #12 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #13 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #14 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #15 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #16 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #17 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #18 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #19 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #20 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #21 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #22 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #23 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #24 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #25 MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:142:11)
I/flutter (20859): #26 _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:339:7)
I/flutter (20859): #27 MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:212:7)
I/flutter (20859): #28 RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:356:14)
I/flutter (20859): #29 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #30 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #31 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #32 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #33 _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1188:11)
I/flutter (20859): #34 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #35 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #36 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #37 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #38 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #39 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #40 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #41 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #42 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #43 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #44 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #45 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #46 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #47 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #48 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #49 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #50 RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:2881:13)
I/flutter (20859): #51 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #52 RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
I/flutter (20859): #53 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #54 __RenderTheatre&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #55 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #56 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #57 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #58 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #59 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #60 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #61 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #62 _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:13)
I/flutter (20859): #63 RenderObject.layout (package:flutter/src/rendering/object.dart:1634:7)
I/flutter (20859): #64 RenderView.performLayout (package:flutter/src/rendering/view.dart:147:13)
I/flutter (20859): #65 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1509:7)
I/flutter (20859): #66 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:768:18)
I/flutter (20859): #67 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:281:19)
I/flutter (20859): #68 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:677:13)
I/flutter (20859): #69 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
I/flutter (20859): #70 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter (20859): #71 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter (20859): #72 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:751:7)
I/flutter (20859): #74 _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19)
I/flutter (20859): #75 _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
I/flutter (20859): #76 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
I/flutter (20859): (elided 3 frames from class _AssertionError and package dart:async)
I/flutter (20859):
I/flutter (20859): The following RenderObject was being processed when the exception was fired:
I/flutter (20859): RenderSliverList#0a44b relayoutBoundary=up1 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (20859): creator: SliverList ← Viewport ← _ScrollableScope ← IgnorePointer-[GlobalKey#d2321] ← Semantics ←
I/flutter (20859): Listener ← _GestureSemantics ←
I/flutter (20859): RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#d6ccd] ←
I/flutter (20859): _ScrollSemantics-[GlobalKey#9f8c8] ← RepaintBoundary ← CustomPaint ← RepaintBoundary ← ⋯
I/flutter (20859): parentData: paintOffset=Offset(0.0, 0.0) (can use size)
I/flutter (20859): constraints: SliverConstraints(AxisDirection.down, GrowthDirection.forward, ScrollDirection.idle,
I/flutter (20859): scrollOffset: 1284.9, remainingPaintExtent: 683.4, overlap: 80.0, crossAxisExtent: 411.4,
I/flutter (20859): crossAxisDirection: AxisDirection.right, viewportMainAxisExtent: 683.4, remainingCacheExtent:
I/flutter (20859): 1183.4 cacheOrigin: -250.0 )
I/flutter (20859): geometry: SliverGeometry(scrollExtent: Infinity, paintExtent: 683.4, maxPaintExtent: Infinity,
I/flutter (20859): hasVisualOverflow: true, cacheExtent: 1183.4)
I/flutter (20859): currently live children: 0 to 0
I/flutter (20859): This RenderObject had the following descendants (showing up to depth 5):
I/flutter (20859): RenderIndexedSemantics#e2e23 relayoutBoundary=up2 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (20859): RenderRepaintBoundary#c0810 relayoutBoundary=up3 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (20859): RenderConstrainedBox#f64ff NEEDS-LAYOUT NEEDS-PAINT
I/flutter (20859): RenderSemanticsGestureHandler#d88b0 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (20859): RenderPointerListener#64372 NEEDS-LAYOUT NEEDS-PAINT
I/flutter (20859): ════════════════════════════════════════════════════════════════════════════════════════════════════
Reloaded 4 of 527 libraries in 761ms.
Я довольно плохо знаком с флаттером и не мог по-настоящему интерпретировать трассировку стека, чтобы понять, что происходит, за исключением того, что WebView каким-то образом путает вычисления высоты макета. Я даже пытался ограничить высоту контейнера, чтобы увидеть, если это имеет значение, но это не так.
Любые указатели / предложения /RTFMs приветствуются.
3 ответа
Я действительно хотел сделать комментарий, но он слишком длинный, чтобы уместиться
Я могу высказать свое мнение о том, почему это невозможно сделать с текущим состоянием плагина, по умолчанию Webview
реагировать на жест перетаскивания только тогда, когда другие представления не утверждают этот жест. С другой стороны, полосы прокрутки похожи наSliverList
, что необходимо для того, чтобы SliverAppBar
для прокрутки вверх по умолчанию используются все жесты прокрутки перетаскиванием -хотя вы можете отключить это, указав noScrollPhysics - но как толькоWebView
покрыть весь экран, который на самом деле теперь не может сообщить осколкам, чтобы снова начать использовать прокрутку.
Итак, решение состоит в том, чтобы изменить WebView plugin
сам, чтобы обеспечить обратный вызов для жестов перетаскивания, надеюсь, что команда flutter скоро реализует эту функцию.
После многих проб и ошибок я нашел способ исправить аналогичную проблему, используя
@override
Widget build(BuildContext context) {
return SliverFillRemaining(
child: WebView(
initialUrl: url,
javascriptMode: JavascriptMode.unrestricted,
gestureRecognizers: {
Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer(),
),
},
),
);
}
Я думаю, вы должны взглянуть на использование SliverFillRemaining
или же SliverFillViewport
вместо SliverList
, Вот пример использования SliverFillRemaining
https://docs.flutter.io/flutter/widgets/SliverFillRemaining-class.html
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
title: const Text("Heading"),
floating: true,
),
SliverFillRemaining(
child: WebView(initialUrl: "http://stackru.com"),
)
],
);
}