FlutterError (A RenderViewport expected a child of type RenderSliver but received a child of type RenderRepaintBoundary

huangapple go评论61阅读模式
英文:

FlutterError (A RenderViewport expected a child of type RenderSliver but received a child of type RenderRepaintBoundary

问题

以下是代码的翻译部分:

异常已发生。
FlutterErrorRenderViewport预期的子类型为RenderSliver,但收到的子类型为RenderRepaintBoundary
渲染对象期望具体类型的子对象,因为它们在布局和绘制过程中与它们的子对象进行协调。例如,RenderSliver不能是RenderBox的子对象,因为RenderSliver不理解RenderBox的布局协议

期望RenderSliver子对象的RenderViewport是由以下方式创建的
Viewport  IgnorePointer-[GlobalKey#4d030]  Semantics  Listener  _GestureSemantics  RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#5be01]  Listener  _ScrollableScope  _ScrollSemantics-[GlobalKey#c19df]  NotificationListener<ScrollMetricsNotification>  RepaintBoundary  CustomPaint  

未匹配期望子类型的RenderRepaintBoundary是由以下方式创建的
RepaintBoundary  NotificationListener<ScrollNotification>  GlowingOverscrollIndicator  Scrollable  CustomScrollView  Viewport 

以上错误是由下面的代码引发的。我在另一个CustomScrollView内部编写了CustomScrollView。第二个CustomScrollView引发了错误。当我不包含第二个CustomScrollView时,代码能够执行,但包含第二个CustomScrollView时会发生错误。我已经尝试使用和不使用RepaintBoundary和sliverToBoxAdapter,但仍然遇到相同的错误。

CustomScrollView(
  slivers: [
    SliverAppBar(
      floating: true,
      pinned: true,
      automaticallyImplyLeading: false,
      elevation: 0,
      backgroundColor: Colors.white,
      bottom: PreferredSize(
        preferredSize: Size.fromHeight(48),
        child: Container(
          padding: EdgeInsets.only(bottom: 10),
          height: 80,
          child: TabBar(
            isScrollable: true,
            controller: _controller,
            tabs: [
              Tab(
                child: tab(text: "tab1", conIn: _controller.index, index: 0),
              ),
              Tab(
                child: tab(text: "tab2", conIn: _controller.index, index: 1),
              ),
              Tab(
                child: tab(text: "tab3", conIn: _controller.index, index: 2),
              ),
            ],
          ),
        ),
      ),
    ),
    CustomScrollView(
      slivers: [
        TabBarView(
          controller: _controller,
          children: [
            RepaintBoundary(
              child: SliverList(
                delegate: SliverChildBuilderDelegate(
                  (context, index) {
                    return Text("");
                  },
                  childCount: 4,
                ),
              ),
            ),
            RepaintBoundary(
              child: SliverList(
                delegate: SliverChildBuilderDelegate(
                  (context, index) {
                    return Text("");
                  },
                  childCount: 4,
                ),
              ),
            ),
            RepaintBoundary(
              child: SliverList(
                delegate: SliverChildBuilderDelegate(
                  (context, index) {
                    return Text("");
                  },
                  childCount: 4,
                ),
              ),
            ),
          ],
        ),
      ],
    ),
  ],
)

应用程序结构如下:

  • Scaffold
  • CustomScrollView
    • SliverAppBar
      • SliverToBoxAdapter
        • Container
    • TabBarView
      • RepaintBoundary
        • SliverList
      • RepaintBoundary
        • SliverList
      • RepaintBoundary
        • SliverList

希望这能帮助您理解问题并解决它。如果您有任何其他问题,请随时提出。

英文:
Exception has occurred.
FlutterError (A RenderViewport expected a child of type RenderSliver but received a child of type RenderRepaintBoundary.
RenderObjects expect specific types of children because they coordinate with their children during layout and paint. For example, a RenderSliver cannot be the child of a RenderBox because a RenderSliver does not understand the RenderBox layout protocol.

The RenderViewport that expected a RenderSliver child was created by:
  Viewport ← IgnorePointer-[GlobalKey#4d030] ← Semantics ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#5be01] ← Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#c19df] ← NotificationListener<ScrollMetricsNotification> ← RepaintBoundary ← CustomPaint ← ⋯

The RenderRepaintBoundary that did not match the expected child type was created by:
  RepaintBoundary ← NotificationListener<ScrollNotification> ← GlowingOverscrollIndicator ← Scrollable ← CustomScrollView ← Viewport ← 

The above error is given by below code.I have written customScrollView inside another customScrollview.The second customScrollView is giving the error.Whenever i write without second customscrollview the code executed,but with second customscrollview the error is occured.I have tried with and without RepaintBoundary,sliverToBoxAdapter,but again again same error occur

code:

CustomScrollView(
        slivers: [
          SliverAppBar(
            floating: true,
            pinned: true,
            automaticallyImplyLeading: false,
            elevation: 0,
            backgroundColor: Colors.white,
            bottom: PreferredSize(preferredSize: Size.fromHeight(48),
            child: Container(
              padding: EdgeInsets.only(bottom: 10),
              height: 80,
              child: TabBar(
                isScrollable: true,
                controller: _controller,
                tabs:  [
                  Tab( 
                    child: tab(text: "tab1",conIn:_controller.index,index:0)
                  ,),
                   Tab(child: tab(text: "tab2",conIn:_controller.index,index:1)
                  ,),
                   Tab(child: tab(text: "tab3",conIn:_controller.index,index:2)
                  ,),
                   
                  
              ]),
            ),),
        ),
     CustomScrollView(
    
  slivers: [
    TabBarView(
      controller: _controller,
      children: [
        RepaintBoundary(
          child: SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return Text("");
              },
              childCount: 4,
            ),
          ),
        ),
         RepaintBoundary(
          child: SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return Text("");
              },
              childCount: 4,
            ),
          ),
        ),
          RepaintBoundary(
          child: SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return Text("");
              },
              childCount: 4,
            ),
          ),
        ),
       
      ],
    ),
  ],
),




        ],
      ),

App structure is:

  • scaffold

  • customScrollView

  • sliverAppBar

  • SliverToBoxAdapter

  • Container

  • TabbarView

  • RepaintBoundary

  • SliverList

List item

答案1

得分: 1

你可以使用ListView.builder与repaintBoundary。

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: CustomScrollView(
      slivers: [
        SliverAppBar(
          floating: true,
          pinned: true,
          automaticallyImplyLeading: false,
          elevation: 0,
          // backgroundColor: Colors.white,
          bottom: PreferredSize(
            preferredSize: Size.fromHeight(80),
            child: Container(
              padding: EdgeInsets.only(bottom: 10),
              height: 80,
              child: TabBar(
                isScrollable: true,
                controller: _controller,
                tabs: [
                  Tab(
                    child: Text("a"),
                  ),
                  Tab(
                    child: Text("a"),
                  ),
                ],
              ),
            ),
          ),
        ),
        SliverFillRemaining(
          child: TabBarView(
            controller: _controller,
            children: [
              RepaintBoundary(
                child: ListView.builder(
                  itemBuilder: (context, index) {
                    return Text("$index");
                  },
                  itemCount: 4,
                ),
              ),
              RepaintBoundary(
                child: ListView.builder(
                  itemBuilder: (context, index) {
                    return Text("$index");
                  },
                  itemCount: 4,
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  );
}

请注意,代码部分已被保留原文。

英文:

You can use ListView.builder with repaintBoundary

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: CustomScrollView(
      slivers: [
        SliverAppBar(
          floating: true,
          pinned: true,
          automaticallyImplyLeading: false,
          elevation: 0,
          // backgroundColor: Colors.white,
          bottom: PreferredSize(
            preferredSize: Size.fromHeight(80),
            child: Container(
              padding: EdgeInsets.only(bottom: 10),
              height: 80,
              child: TabBar(
                isScrollable: true,
                controller: _controller,
                tabs: [
                  Tab(
                    child: Text("a"),
                  ),
                  Tab(
                    child: Text("a"),
                  ),
                ],
              ),
            ),
          ),
        ),
        SliverFillRemaining(
          child: TabBarView(
            controller: _controller,
            children: [
              RepaintBoundary(
                child: ListView.builder(
                  itemBuilder: (context, index) {
                    return Text("$index");
                  },
                  itemCount: 4,
                ),
              ),
              RepaintBoundary(
                child: ListView.builder(
                  itemBuilder: (context, index) {
                    return Text("$index");
                  },
                  itemCount: 4,
                ),
              ),
            ],
          ),
        ),
      ],
    ),
  );
}

答案2

得分: 0

the slivers接受来自Sliver小部件系列的小部件,如SliverListSliverPadding等,但即使它内部包含一个sliver,你也在直接添加一个非sliver的小部件,你需要在slivers中直接公开一个sliver。

有一个SliverToBoxAdapter(),它可以将任何Flutter小部件调整为可在内部用作sliver,只需像这样将RepaintBoundary包装起来:

SliverToBoxAdapter(
  child: RepaintBoundary(
    // ...
  ),
),
英文:

the slivers accepts widgets from the Sliver widgets family, such as SliverList, SliverPadding..., but you're adding directly a non-silver's, even if it contains inside of it a sliver one, you need to expose a sliver directly in slivers.

There is a SliverToBoxAdapter() that adapts any Flutter widget to be used inside as a sliver, just wrap the RepaintBoundary with it like this:

SliverToBoxAdapter(
  child: RepaintBounder(
   // ...
 ),
),

huangapple
  • 本文由 发表于 2023年2月8日 19:18:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75385003.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定