flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.1k stars 27.43k forks source link

Add sliver widget to bundle slivers #77474

Closed friebetill closed 3 years ago

friebetill commented 3 years ago

Use case

I have a CustomScrollView with the following structure:

body: CustomScrollView(
  slivers: <Widget>[
    MyCustomSliverTitle(...),
    MyCustomSliverFixedExtendList(...),
    ...
  ],
),

MyCustomSliverTitle extends StatelessWidget and in the build method returns a SliverToBoxAdapter widget, and the MyCustomSliverFixedExtendList widget extends StatelessWidget and in the build method returns a SliverFixedExtentList widget.

How can I implement a single Widget (MyCustomSliverListWithTitle) that returns both the custom title and the custom list?

I tried to solve this problem in MyCustomSliverListWithTitle with the following widgets:

When the exception was thrown, this was the stack:

0 RenderSliverFixedExtentBoxAdaptor.performLayout package:flutter/…/rendering/sliver_fixed_extent_list.dart:190

1 RenderObject.layout package:flutter/…/rendering/object.dart:1777

2 RenderViewportBase.layoutChildSequence package:flutter/…/rendering/viewport.dart:507

3 RenderShrinkWrappingViewport._attemptLayout package:flutter/…/rendering/viewport.dart:1904

4 RenderShrinkWrappingViewport.performLayout package:flutter/…/rendering/viewport.dart:1862

5 RenderObject.layout package:flutter/…/rendering/object.dart:1777

6 RenderProxyBoxMixin.performLayout package:flutter/…/rendering/proxy_box.dart:113

7 RenderObject.layout package:flutter/…/rendering/object.dart:1777

8 RenderProxyBoxMixin.performLayout package:flutter/…/rendering/proxy_box.dart:113

9 RenderObject.layout package:flutter/…/rendering/object.dart:1777

...


- `SliverList`
```dart
class MyCustomSliverListWithTitle ... {

  ...
  @override
  Widget build(BuildContext context) {
    return SliverList(
          delegate: SliverChildListDelegate([
              MyCustomSliverTitle(...), // This returns a sliver, but a box was expected
              MyCustomSliverFixedExtendList(...), // This returns a sliver, but a box was expected
          ]),
    );
  }
}

This leads to this error

A RenderRepaintBoundary expected a child of type RenderBox but received a child of type
SliverToBoxAdapter.
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.

A solution would be nice to have, because I am using an MVVM architecture and both MyCustomSliverTitle and MyCustomSliverFixedExtendList access data from the ViewModel. In addition, it also helps with the separations of concerns.

The problem description is inspired by this StackOverflow question.

Proposal

Solutions that came to my mind for now:

But maybe there is a solution already and I haven't found it yet.

darshankawar commented 3 years ago

@friebetill Can you check out this article and see if it helps ?

friebetill commented 3 years ago

@darshankawar Thanks for your reply.

The article introduces the three (four) sliver widgets:

I can't use any of the three (four) widgets because I have two sliver widgets and want to display them in a column. But SliverToBoxAdapter, SliverList and SliverGrid expect box widget(s).

Piinks commented 3 years ago

I think this is a dupe of https://github.com/flutter/flutter/issues/33137 And it looks like there is a package that does this: https://pub.dev/packages/sliver_tools

darshankawar commented 3 years ago

@friebetill Check out the original issue and follow-up there for updates. You may also check out the plugin listed and see if it serves your purpose. Closing from here for now. If you disagree, write in comments and I'll reopen it. Thanks.

github-actions[bot] commented 3 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.