Unity-Technologies / com.unity.uiwidgets

UIWidgets is a Unity Package which helps developers to create, debug and deploy efficient, cross-platform Apps.
https://unity.cn/uiwidgets
627 stars 78 forks source link

自定义SliverPersistentHeaderDelegate中的异常 #315

Closed tomcatter closed 2 years ago

tomcatter commented 2 years ago

我根据CustomScrollView 和 Slivers的介绍,实现了一个自定义的SliverPersistentHeaderDelegate,代码如下

  public delegate Widget SliverHeaderBuilder(BuildContext context, float shrinkOffset, bool overlapsContent);

    public class SliverHeaderDelegate : SliverPersistentHeaderDelegate
    {

        private float maxHeight;
        private float minHeight;

        private SliverHeaderBuilder builder;

        public SliverHeaderDelegate(
            Widget child,
            float maxHeight,
            float minHeight = 0,
            SliverHeaderBuilder builder = null
            )
        {
            this.minHeight = minHeight;
            this.maxHeight = maxHeight;
            this.builder = builder ??= (BuildContext context, float shirnk, bool overlaps) => child;
            D.assert(minHeight <= maxHeight && minHeight >= 0);
        }

        public static SliverHeaderDelegate fixedHeight(
            float height,
            Widget child
            )
        {
            SliverHeaderBuilder builder = (BuildContext context, float shirnk, bool overlaps) => child;
            return new SliverHeaderDelegate(
                maxHeight: height,
                minHeight: height,
                child: child,
                builder: builder
                );
        }

        public static SliverHeaderDelegate build(
            float maxHeight,
            SliverHeaderBuilder builder,
            float minHeight = 0
            )
        {
            return new SliverHeaderDelegate(
                maxHeight: maxHeight,
                minHeight: minHeight,
                builder: builder,
                child: null
                );
        }

        public override Widget build(BuildContext context, float shrinkOffset, bool overlapsContent)
        {
            Widget child = builder(context, shrinkOffset, overlapsContent);

            return SizedBox.expand(child: child);
        }

        public override float? maxExtent => maxHeight;

        public override float? minExtent => minHeight;

        public override bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate)
        {
            return oldDelegate.maxExtent != maxExtent || oldDelegate.minExtent != minExtent;
        }
    }

布局代码如下:

new CustomScrollView(
                shrinkWrap: true,
                physics: new BouncingScrollPhysics(),
                slivers: new List<Widget>
                {
                      // other code 
                    new SliverPersistentHeader(
                        del: SliverHeaderDelegate.fixedHeight(
                            height: 40,
                            child: new Container(
                                child: new Text(
                                    data: "桌面",
                                    style: new TextStyle(
                                        color: Color.fromRGBO(255, 255, 255, 1),
                                        fontSize: 18,
                                        fontWeight: FontWeight.w500,
                                        fontFamily: Fonts.PFSCMedium,
                                        decoration: TextDecoration.none
                                    )
                                )
                            )
                        )
                    )
                  // other code
                }
            )

出现如下异常:

AssertionError: EXCEPTION CAUGHT BY RENDERING LIBRARY
The null value was thrown  during performLayout.
The null value was thrown  during performLayout.

The following RenderObject was being processed when the exception was fired: Unity.UIWidgets.widgets._RenderSliverScrollingPersistentHeaderForWidgets#55100 relayoutBoundary=up8 NEEDS-LAYOUT NEEDS-PAINT:
  creator: Unity.UIWidgets.widgets._SliverScrollingPersistentHeader ←
    Unity.UIWidgets.widgets.SliverPersistentHeader ← Unity.UIWidgets.widgets.ShrinkWrappingViewport ←
    Unity.UIWidgets.widgets.IgnorePointer-[GlobalKey#25800] ← Unity.UIWidgets.widgets._PointerListener
    ← Unity.UIWidgets.widgets.Listener ← Unity.UIWidgets.widgets.RawGestureDetector-[GlobalKey#FE000]
    ← Unity.UIWidgets.widgets._PointerListener ← Unity.UIWidgets.widgets.Listener ←
    Unity.UIWidgets.widgets._ScrollableScope ← Unity.UIWidgets.widgets.Scrollable ←
    Unity.UIWidgets.widgets.PrimaryScrollController ← ⋯
  parentData: layoutOffset = None(can use size)
    parentData: layoutOffset = None(can use size)
  constraints: SliverConstraints(down, forward, idle, scrollOffset:  F1, remainingPaintExtent:  F1,
    crossAxisExtent:  F1, crossAxisDirection: right, viewportMainAxisExtent:  F1,
    remainingCacheExtent:  F1, cacheOrigin:  F1)
  geometry
  geometry
  maxExtent: EXCEPTION (System.NullReferenceException)
    maxExtent: EXCEPTION (System.NullReferenceException)
  child position: 0.0
    child position: 0.0
This RenderObject has no descendants.
Unity.UIWidgets.widgets._RenderSliverScrollingPersistentHeaderForWidgets.get_maxExtent () (at Packages/com.unity.uiwidgets/Runtime/widgets/sliver_persistent_header.cs:237)
Unity.UIWidgets.rendering.RenderSliverScrollingPersistentHeader.performLayout () (at Packages/com.unity.uiwidgets/Runtime/rendering/sliver_persistent_header.cs:194)
Unity.UIWidgets.widgets._RenderSliverPersistentHeaderForWidgetsMixinOnRenderSliverPersistentHeaderRenderSliverScrollingPersistentHeader.performLayout () (at Packages/com.unity.uiwidgets/Runtime/widgets/sliver_persistent_header.mixin.gen.cs:235)
Unity.UIWidgets.rendering.RenderObject.layout (Unity.UIWidgets.rendering.Constraints constraints, System.Boolean parentUsesSize) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
UnityEngine.Debug:LogException(Exception)
Unity.UIWidgets.foundation.D:logError(String, Exception) (at Packages/com.unity.uiwidgets/Runtime/foundation/debug.cs:63)
Unity.UIWidgets.foundation.UIWidgetsError:dumpErrorToConsole(UIWidgetsErrorDetails, Boolean) (at Packages/com.unity.uiwidgets/Runtime/foundation/assertions.cs:373)
Unity.UIWidgets.foundation.UIWidgetsError:dumpErrorToConsole(UIWidgetsErrorDetails) (at Packages/com.unity.uiwidgets/Runtime/foundation/assertions.cs:357)
Unity.UIWidgets.foundation.UIWidgetsError:reportError(UIWidgetsErrorDetails) (at Packages/com.unity.uiwidgets/Runtime/foundation/assertions.cs:407)
Unity.UIWidgets.rendering.RenderObject:_debugReportException(String, Exception) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:603)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:954)
Unity.UIWidgets.rendering.RenderViewportBase`1:layoutChildSequence(RenderSliver, Single, Single, Single, Single, Single, Single, GrowthDirection, Func`2, Single, Single) (at Packages/com.unity.uiwidgets/Runtime/rendering/viewport.cs:256)
Unity.UIWidgets.rendering.RenderShrinkWrappingViewport:_attemptLayout(Single, Single, Single) (at Packages/com.unity.uiwidgets/Runtime/rendering/viewport.cs:1357)
Unity.UIWidgets.rendering.RenderShrinkWrappingViewport:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/viewport.cs:1312)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderPadding:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/shifted_box.cs:188)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderFlex:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/flex.cs:494)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderPositionedBox:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/shifted_box.cs:331)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderPositionedBox:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/shifted_box.cs:331)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderPadding:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/shifted_box.cs:188)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderConstrainedBox:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.cs:229)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderFlex:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/flex.cs:426)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderFlex:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/flex.cs:426)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderPadding:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/shifted_box.cs:188)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderPadding:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/shifted_box.cs:188)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderConstrainedBox:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.cs:229)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderStack:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/stack.cs:451)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderFlex:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/flex.cs:426)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderStack:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/stack.cs:451)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderConstrainedBox:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.cs:229)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderPositionedBox:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/shifted_box.cs:331)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.MultiChildLayoutDelegate:layoutChild(Object, BoxConstraints) (at Packages/com.unity.uiwidgets/Runtime/rendering/custom_layout.cs:63)
Unity.UIWidgets.material._ScaffoldLayout:performLayout(Size) (at Packages/com.unity.uiwidgets/Runtime/material/scaffold.cs:424)
Unity.UIWidgets.rendering.MultiChildLayoutDelegate:_callPerformLayout(Size, RenderBox) (at Packages/com.unity.uiwidgets/Runtime/rendering/custom_layout.cs:128)
Unity.UIWidgets.rendering.RenderCustomMultiChildLayoutBox:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/custom_layout.cs:265)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering._RenderCustomClip`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.cs:940)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderPadding:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/shifted_box.cs:188)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.rendering.RenderProxyBoxMixinRenderObjectWithChildMixinRenderBox`1:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.mixin.gen.cs:70)
Unity.UIWidgets.rendering.RenderOffstage:performLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/proxy_box.cs:2632)
Unity.UIWidgets.rendering.RenderObject:layout(Constraints, Boolean) (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:947)
Unity.UIWidgets.widgets._RenderTheatre:performLayout() (at Packages/com.unity.uiwidgets/Runtime/widgets/overlay.cs:540)
Unity.UIWidgets.rendering.RenderObject:_layoutWithoutResize() (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:831)
Unity.UIWidgets.rendering.PipelineOwner:flushLayout() (at Packages/com.unity.uiwidgets/Runtime/rendering/object.cs:456)
Unity.UIWidgets.rendering.RendererBinding:drawFrame() (at Packages/com.unity.uiwidgets/Runtime/rendering/binding.cs:113)
Unity.UIWidgets.widgets.WidgetsBinding:drawFrame() (at Packages/com.unity.uiwidgets/Runtime/widgets/binding.cs:200)
Unity.UIWidgets.rendering.RendererBinding:_handlePersistentFrameCallback(TimeSpan) (at Packages/com.unity.uiwidgets/Runtime/rendering/binding.cs:81)
Unity.UIWidgets.scheduler.SchedulerBinding:_invokeFrameCallback(FrameCallback, TimeSpan, String) (at Packages/com.unity.uiwidgets/Runtime/scheduler/binding.cs:729)
Unity.UIWidgets.scheduler.SchedulerBinding:handleDrawFrame() (at Packages/com.unity.uiwidgets/Runtime/scheduler/binding.cs:658)
Unity.UIWidgets.scheduler.SchedulerBinding:_handleDrawFrame() (at Packages/com.unity.uiwidgets/Runtime/scheduler/binding.cs:593)
Unity.UIWidgets.ui.Hooks:Window_drawFrame() (at Packages/com.unity.uiwidgets/Runtime/ui/hooks.cs:181)
zhuxingwei commented 2 years ago

Hi Thanks for the bug report!

We will investigate this issue asap. However, affected by the recent situation of covid-19 in Shanghai, our development schedule might be delayed in some degree

zhuxingwei commented 2 years ago

This issue is fixed in #317

tomcatter commented 2 years ago

问题修复了

tomcatter commented 2 years ago

@zhuxingwei 还有一个问题是CustomScrollView在用鼠标滚轮上下滚动时,显示内容的滚动和鼠标的滚动方向相反,体验起来感觉挺别扭,不太符合平时网页滚动。

zhuxingwei commented 2 years ago

Hi, thanks for your feedback!

The current interaction with mouse scroll events is designed by our designer. We will arrange a talk on this issue later. Btw, does this seem to be a common problem on all ScrollViews (e.g., singlechildscrollview) ?

tomcatter commented 2 years ago

Hi, thanks for your feedback!

The current interaction with mouse scroll events is designed by our designer. We will arrange a talk on this issue later. Btw, does this seem to be a common problem on all ScrollViews (e.g., singlechildscrollview) ?

现在我只用到了 CustomScrollView, 发现的是这种情况。