sliver_tools icon indicating copy to clipboard operation
sliver_tools copied to clipboard

SliverPinnedFooter

Open volser opened this issue 4 years ago • 26 comments

Is it possible to implement SliverPinnedFooter?

volser avatar Jan 05 '21 11:01 volser

Can you elaborate on how this widget should work?

Kavantix avatar Jan 05 '21 11:01 Kavantix

the same as header, but pin at the bottom next header in the list

volser avatar Jan 05 '21 12:01 volser

actually, I have a reversed list and need to implement pinned header, but for reversed list it works like footer :-)

volser avatar Jan 05 '21 12:01 volser

in this demo https://raw.githubusercontent.com/Kavantix/sliver_tools/master/gifs/demo2.gif "Next button" should be pinned to the bottom if list is longer than screen

volser avatar Jan 05 '21 12:01 volser

Hmm ok And what if there are multiple? I guess only 1 should be visible?

Kavantix avatar Jan 05 '21 12:01 Kavantix

yes, only 1, the same as header, but reversed logic, when scroll up, prev (I mean footer above) footer should shift next (footer below)

volser avatar Jan 05 '21 12:01 volser

That does complicate things somewhat since they would need to communicate with each other in order to achieve this within the current flutter sliver implementation. Possibly it would even need a parent inherited widget above the viewport to make this work.

Thanks for the suggestion though, I'll put it on the project but I won't have time to work on this in the near future, feel free to make a PR

Kavantix avatar Jan 06 '21 11:01 Kavantix

@Kavantix Would be great if you could elaborate on why the whole thing would get complicated. I want to build the same thing, and I am struggling with it, but I am also new to slivers. Any tips & trick or hints are appreciated.

saibotma avatar Jan 03 '22 12:01 saibotma

@saibotma could you elaborate a bit more on the exact usecase you are trying to implement because only a subset of usecases would be as complicated as I mentioned

Kavantix avatar Jan 03 '22 12:01 Kavantix

I am actually trying to have a bottom (tab) bar for navigation, where scrollable content scrolls beneath it. I want to make the bottom bar opaque in order to add a blur filter and create an iOS style frosted glass effect. Currently, I have implemented it using a Stack. The bottom bar is above the scrolled content and aligned to the bottom. The scrolled content has padding bottom as high as the bottom bar. However, this feels very hacky, and you always have to know the height of the bottom bar (which can change in my case).

saibotma avatar Jan 03 '22 12:01 saibotma

Ah I see, that usecase is indeed quite a bit simpler than what I was talking about since you only have 1 tab bar and thus don't need any logic for having multiple.

However, the part you mention where it should draw on top of the other content makes it rather difficult. The thing with slivers is that they are painted in the reverse order, this is why a SliverPinnedHeadere is painted on top of the other widgets. This means that in order to have a footer draw over content it needs to be earlier in the list of slivers which would remove the ability to fill up space in the bottom.

So making this a Sliver is probably not the best option. Just keep using the Stack. To solve the problem of not knowing the size of the tab bar you can put an invisible widget at the end of the CustomScrollView that sizes in the same way as the tab bar does (you could even start by actually putting the tab bar there but invisible)

Kavantix avatar Jan 03 '22 12:01 Kavantix

This might be another use case where SliverPinnedFooter makes sense. I want to pin the Total row at the bottom but as of now without using shrinkWrap I am not being able to do so. Is there any better way to achieve this behaviour?

image

    Column(
         mainAxisSize: MainAxisSize.min,
         children: [
            // Header
            const _Header(),

            // Body
            Flexible(
                  child: CustomScrollView(
                    // Shrink wrapping the content of the scroll view is
                    // significantly more expensive than expanding to the
                    // maximum allowed size because the content can expand
                    // and contract during scrolling, which means the size
                    // of the scroll view needs to be recomputed whenever
                    // the scroll position changes.
                    shrinkWrap: provider.body.rows.length < 30,
                    physics: const ClampingScrollPhysics(),
                    slivers: const [_Body()],
                  ),
             ),

            // Footer
            const _Header(header: false),
       ],
  ),

koiralapankaj7 avatar Aug 22 '22 20:08 koiralapankaj7

@volser @koiralapankaj7 I just opened a draft PR #59 that should serve your needs. I would like some feedback if you have time to test it :)

Kavantix avatar Sep 03 '22 22:09 Kavantix

@Kavantix Thank you so much for this update. I just tested it and it is working perfectly fine. I have one suggestion:

  1. Footer should push pinned children if there are any.

koiralapankaj7 avatar Sep 05 '22 15:09 koiralapankaj7

Great to hear it works! But can you elaborate a bit on the question?

Kavantix avatar Sep 05 '22 15:09 Kavantix

https://user-images.githubusercontent.com/19282888/188480667-6792e01c-6f90-4503-9baf-0238ddddde70.mov

In this video, the footer is going below the header while scrolling. What I meant was can we push the header when the footer reaches there? (header in this context is SliverPinnedHeader.)

koiralapankaj7 avatar Sep 05 '22 15:09 koiralapankaj7

You can try wrapping the multisliver with the sliverwithpinnedfooter

Kavantix avatar Sep 05 '22 15:09 Kavantix

image

If I am using MultiSliver correctly, it seems like it is not working for SliverWithPinnedFooter.

koiralapankaj7 avatar Sep 05 '22 15:09 koiralapankaj7

Well I meant try using it like this:

SliverWithPinnedFooter(
  sliver: MultiSliver(
    pushPinnedChildren: true,
    children: [...],
  ),
  footer: FooterWidget(),
)

Kavantix avatar Sep 05 '22 15:09 Kavantix

image

If I use MultiSliver inside SliverWithPinnedFooter then the footer is behaving quite differently. If you need I will attach a video as well.

koiralapankaj7 avatar Sep 05 '22 15:09 koiralapankaj7

video would be helpful

Kavantix avatar Sep 05 '22 15:09 Kavantix

https://user-images.githubusercontent.com/19282888/188484086-f29e68f3-3530-4a7a-bf6a-cd20bf61c7aa.mov

If you notice at the bottom. Footer appears before the header.

koiralapankaj7 avatar Sep 05 '22 15:09 koiralapankaj7

Hmmm, supporting this might require the widget to be changed to SliverWithPinnedFooterAndHeader I'll have to think about it a bit more

Kavantix avatar Sep 05 '22 16:09 Kavantix