Могу ли я использовать 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"),
        )
      ],
    );
  }
Другие вопросы по тегам