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

SliverPinnedHeader Enhancement #25

Closed
Peng-Qian opened this issue Mar 15, 2021 · 12 comments
Closed

SliverPinnedHeader Enhancement #25

Peng-Qian opened this issue Mar 15, 2021 · 12 comments

Comments

@Peng-Qian
Copy link

Hi @Kavantix

Thx for your awesome package! It makes Sliver more flexible and powerful!

I am wondering if it is possible to introduce more prop to control SliverPinnedHeader.

Such as a position to set where to pin (e.g. pin at the 300px from top) and a controller to control when to pin?

I think this may also solve #20 request

@Kavantix
Copy link
Owner

I’m glad you like the package!

A leadingMargin is something I was already intending to do, if you want it I can see if I can prioritize it a bit more.

The controller part I don’t completely get, how do you have that in mind?

@Peng-Qian
Copy link
Author

Peng-Qian commented Mar 16, 2021

@Kavantix,

A leading margin will be sufficient for most scenarios. So excited about this feature, can't wait to use that! (Currently, I use CompositedTransformTarget and CompositedTransformFollower with a complicated logic to handle this 😞 )

The controller/pinned is just control if the widget should be pinned, In some cases, we allow the user to choose if something needs to be pinned or not. But It is not that important since I believe this also can be achieved by changing the widget parent from SliverPinnedHeader to SliverToBoxAdapter.

Another thing I can think of: a widget builder will be super helpful, so the widget can be different when pinned

typedef Widget SliverPinnedHeaderWidgetBuilder(
  BuildContext context,
  SliverPinnedHeaderState state,
);

SliverPinnedHeader(
    builder: (context, state) {
      return AnimatedSwitcher(
        duration: const Duration(milliseconds: 300),
        transitionBuilder: (child, animation) => ...,
        child: state.isPinned
            ? Container(key: const ValueKey('blue'), color: Colors.blue)
            : Container(key: const ValueKey('red'), color: Colors.red),
      );
    },
  )

@Kavantix
Copy link
Owner

Hmm adding the leading margin comes with a few decisions I'm not ready to make atm.
Like should it use the paintOrigin to shift itself or simply extend the paintExtent.

But @Peng-Qian why do you need the CompositedTransformTarget can't you simply use something like:

Widget build(BuildContext context) {
  final double leadingMargin = 20;
  return SliverPinnedHeader(
    child: Container(
      margin: const EdgeInsets.only(top: leadingMargin),
      child: YourChildWidget(),
    ),
  );
}

@Peng-Qian
Copy link
Author

sorry for confusing here, I mean I have used CompositedTransformTarget with stack to implement a sticker, it can stick to any position but with complex logic... and that is the reason why so happy to find this package~

@Peng-Qian
Copy link
Author

Peng-Qian commented Mar 21, 2021

In my use case, the widget will only be pinned when it reaches to appbar, and it will be pushed by the next pinned header. Thus, add margin will break UI looking when pinned header does not reach appbar.

@Kavantix
Copy link
Owner

Kavantix commented Mar 21, 2021

Still sounds like something you could do with a margin and a multisliver
Take a look at the example app I built, it does something similar I think.
If not you could share some more specific code and I’d be more than happy to help.

After reading your comment again:

Thus, add margin will break UI looking when pinned header does not reach appbar.

Do you mean that if you’d add the margin then it would also be there when it’s not yet pinned and that would not work for your layout?
If so then it sounds like it being pinned is not the thing you want to toggle (because that only happens at the edge anyways) but you want to artificially increase its size without it affecting your layout and thus the leadingmargin I indent to add wouldn’t help.

Perhaps to get this effect you could use a custom pinned sliver with a paintExtent of the size you want between the top and your pinned sliver and the top but which has no layoutExtent such that it doesnt affect the layout of your view and put that above it?
This would work because the pinned header checks the overlap property such that it doesnt overlap with another pinned header. And a sliver being pinned is nothing more then it always having a paintExtent even though according to the layoutExtent it had already scrolled away.

@Peng-Qian
Copy link
Author

Do you mean that if you’d add the margin then it would also be there when it’s not yet pinned and that would not work for your layout?

Yes, The effect more like the following gif, The flutter_sticky_header can achieve the effect, but the thing is this package does not support a nested pinned header.

sticky_header_all

Perhaps to get this effect you could use a custom pinned sliver with a paintExtent of the size you want between the top and your pinned sliver and the top but which has no layoutExtent such that it doesnt affect the layout of your view and put that above it?
This would work because the pinned header checks the overlap property such that it doesnt overlap with another pinned header. And a sliver being pinned is nothing more then it always having a paintExtent even though according to the layoutExtent it had already scrolled away.

I am a little bit confused about this part. Do you mean I should pin an invisible header on the top and then it can keep a distance when the following header pinned?

@Kavantix
Copy link
Owner

Do you mean that if you’d add the margin then it would also be there when it’s not yet pinned and that would not work for your layout?

Yes, The effect more like the following gif, The flutter_sticky_header can achieve the effect, but the thing is this package does not support a nested pinned header.

sticky_header_all

Which part do you mean? I don’t really see a part that matches what you told me before

Perhaps to get this effect you could use a custom pinned sliver with a paintExtent of the size you want between the top and your pinned sliver and the top but which has no layoutExtent such that it doesnt affect the layout of your view and put that above it?
This would work because the pinned header checks the overlap property such that it doesnt overlap with another pinned header. And a sliver being pinned is nothing more then it always having a paintExtent even though according to the layoutExtent it had already scrolled away.

I am a little bit confused about this part. Do you mean I should pin an invisible header on the top and then it can keep a distance when the following header pinned?

Yes pretty much

@Peng-Qian
Copy link
Author

Peng-Qian commented Mar 25, 2021

Which part do you mean? I don’t really see a part that matches what you told me before

any sticky header on the gif. But in my case, the situation are more complicated.

There are nested scroll views and items can go behind the app bar, which means the scroll view starts at the top of the screen, and the header should be pinned under the app bar. I insert an invisible sliver app bar to achieve the effect with this package(I think that similar to what you talk about). But what I try to do now, is pinned another header under the sticky header(e.g. pin an orange circle header under blue header 1 on the gif).

all in all, I am trying to nested another sticky header under another sticky header properly. 😂

@Kavantix
Copy link
Owner

You should be able to use MultiSliver combined with the pinned header for that.

Perhaps you can share some code?

@Kavantix
Copy link
Owner

@Peng-Qian have you managed to get it working?

@Kavantix
Copy link
Owner

Kavantix commented Jun 5, 2021

I’m gonna close this issue, if you want me to reopen feel free to comment and I’ll do so

@Kavantix Kavantix closed this as completed Jun 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants