Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Material Design "Subheaders" #466

Closed
HansMuller opened this issue Nov 18, 2015 · 17 comments
Closed

Support for Material Design "Subheaders" #466

HansMuller opened this issue Nov 18, 2015 · 17 comments
Labels
c: new feature Nothing broken; request for a new capability customer: crowd Affects or could affect many people, though not necessarily a specific customer. f: material design flutter/packages/flutter/material repository. f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project

Comments

@HansMuller
Copy link
Contributor

http://www.google.com/design/spec/components/subheaders.html

Upon scrolling, subheaders remain pinned to the top of the screen until pushed on or off screen by the next subheader.

In the example below, the subheader text is blue.

Material Design Subheader example

@HansMuller HansMuller added the c: new feature Nothing broken; request for a new capability label Nov 18, 2015
@sethladd sethladd added the f: material design flutter/packages/flutter/material repository. label Nov 18, 2015
@Hixie Hixie modified the milestone: Blue Sky Nov 20, 2015
@Hixie Hixie added the framework flutter/packages/flutter repository. See also f: labels. label Nov 20, 2015
@Hixie Hixie added the f: scrolling Viewports, list views, slivers, etc. label Sep 23, 2016
@Hixie Hixie self-assigned this Sep 23, 2016
@Hixie Hixie removed their assignment Mar 9, 2017
@levrik
Copy link
Contributor

levrik commented Sep 2, 2017

Would really like to see that in the framework. Any pointers on how to achieve that already at the moment? @Hixie @HansMuller

@Hixie
Copy link
Contributor

Hixie commented Sep 3, 2017

It would probably have to be a sliver that has a list of slivers and knows about the sticky header logic, a bit like a combination of RenderSliverList, RenderSliverPadding, and RenderSliverPersistentHeader. We would definitely welcome a patch that did this. It's a little subtle though.

It's something we will do eventually but we don't expect to have this done any time soon.

@levrik
Copy link
Contributor

levrik commented Nov 19, 2017

@Hixie Can you give me a few more hints? I'm completely lost and I really don't want to move to React Native or Xamarin.

@Hixie
Copy link
Contributor

Hixie commented Nov 20, 2017

I recommend starting to pull a thread starting with SliverAppBar. Follow through how it's built, and eventually you'll reach RenderSliverPersistentHeader, see how it's built (notably, how its performLayout method works to keep itself on-screen). Then, follow a thread from SliverPadding and see how RenderSliverPadding works (notably, how it wraps its child).

You want to create a RenderSliver subclass that works like a combination of those two. It would have two children, a RenderBox that ends up being the header (just like RenderSliverPersistentHeader), and a RenderSliver that it wraps (just like RenderSliverPadding). Then you have to get the performLayout method to do the maths correctly to handle both of them at the same time. You'll also have to implement the paint() method and hitTest() method to pass down the paint and hittest calls, but that part should be somewhat simpler.

A lot of this is actually documented in some detail, see the docs for RenderSliver, AbstractNode (the super class of RenderObject), methods like performLayout or paint, etc. For slivers specifically, lots of docs exist on the various properties of SliverConstraints and SliverGeometry, which you'll need to implement the layout method.

I'm sorry this isn't simpler. Feel free to ask specific questions if you run into trouble.

@levrik
Copy link
Contributor

levrik commented Nov 20, 2017

@Hixie Thanks. I will give it a second try next weekend.

@voliva
Copy link

voliva commented Jun 7, 2018

Any update on this feature? As a workaround I see there's this package https://github.com/itsJoKr/sticky_header_list that seems to do the trick

Edit - There's this other implementation as well: https://github.com/slightfoot/flutter_sticky_headers

@letsar
Copy link
Contributor

letsar commented Jun 16, 2018

@voliva I created a package for sticky headers as sliver here: https://github.com/letsar/flutter_sticky_header. It takes a widget as header and a sliver as child. I hope I created it as @Hixie explained it.

Does it match your requirements?

@Hixie
Copy link
Contributor

Hixie commented Jun 16, 2018

@letsar that looks awesome. my only comment would be that the percentage observer won't work well because it'll always lag by one frame.

@letsar
Copy link
Contributor

letsar commented Jun 17, 2018

Thanks @Hixie. Yes it's true for the lag 😞. Do you know how to fix this?

@Hixie
Copy link
Contributor

Hixie commented Jun 18, 2018

You could create a kind of RenderObject that takes the percentage as one of the constraints. Maybe its constraints could be a class with a double (the percentage) and a BoxConstraints object, and its child would be a RenderBox to which you pass the BoxConstraints. If you model this render object after the LayoutBuilder widget and its render object, you can have the same API you have today but without the lag. It's a rather advanced use of Flutter's API, but hey, no worse than slivers, and you seemed to handle that pretty well. :-)

@letsar
Copy link
Contributor

letsar commented Jun 18, 2018

Oh great, thank you! Challenge accepted 😄. I will give it a try after finishing the work in progress on the next feature. Maybe I'll come back to you later, once I dive in the lag issue.
By the way, thank you for your work on the Flutter SDK 👍.

@letsar
Copy link
Contributor

letsar commented Jun 23, 2018

@Hixie I worked on a solution for the scroll percentage to not lag by one frame, by following your explanation. Thanks again, your instructions were very clear 👍.

If you have time, can you tell me if it's what you had in mind?
The code is on this branch: https://github.com/letsar/flutter_sticky_header/tree/feature/2_percentage_observer

@Hixie
Copy link
Contributor

Hixie commented Jun 23, 2018

Yep, that's pretty much it!

@Piinks Piinks self-assigned this Oct 28, 2019
@Piinks
Copy link
Contributor

Piinks commented Oct 28, 2019

Upon scrolling, subheaders remain pinned to the top of the screen until pushed on or off screen by the next subheader.

I'm working on a SliverGroup project that will enable the pinned-then-pushed behavior described here for SliverPersistentHeader. I should have a doc/propsed changes ready for feedback soon.

Here's an updated link to subheaders (under anatomy) in the Material spec: https://material.io/components/lists/#anatomy

@HansMuller Any thoughts on if there should be a stand alone material subheader widget devoted to this? Or does updating SliverPersistentHeader sound appropriate? I am thinking a whole other header widget will be confusing.

@HansMuller
Copy link
Contributor Author

Updating SliverPersistentHeader's API to support subheaders sounds like a good approach to me.

@Hixie Hixie removed this from the Stretch Goals milestone Jan 7, 2020
@Hixie Hixie added this to the New Stretch Goals milestone Jan 7, 2020
@Hixie Hixie unassigned Piinks Jan 7, 2020
@VladyslavBondarenko VladyslavBondarenko added the customer: crowd Affects or could affect many people, though not necessarily a specific customer. label Mar 23, 2020
@kf6gpe kf6gpe added the P3 Issues that are less important to the Flutter project label May 29, 2020
@kf6gpe kf6gpe modified the milestone: Stretch Goals Jun 1, 2020
@Hixie Hixie removed this from the [DEPRECATED] Stretch Goals milestone Jun 16, 2020
@kf6gpe kf6gpe removed this from the [DEPRECATED] Stretch Goals milestone Jul 7, 2020
@kf6gpe kf6gpe modified the milestone: [DEPRECATED] Stretch Goals Jul 22, 2020
@Hixie Hixie removed this from the - milestone Aug 17, 2020
@Hixie
Copy link
Contributor

Hixie commented Feb 5, 2021

There are a number of packages that do this now: https://pub.dev/packages?q=sliver+header

@Hixie Hixie closed this as completed Feb 5, 2021
@github-actions
Copy link

github-actions bot commented Aug 6, 2021

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: new feature Nothing broken; request for a new capability customer: crowd Affects or could affect many people, though not necessarily a specific customer. f: material design flutter/packages/flutter/material repository. f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. P3 Issues that are less important to the Flutter project
Projects
None yet
Development

No branches or pull requests

9 participants