Skip to content

Conversation

@HansMuller
Copy link
Contributor

@HansMuller HansMuller commented Jul 1, 2024

A sliver that shows its [child] when the user scrolls forward and hides it when the user scrolls backwards. Similar headers can be found in Google Photos and Facebook.

This sliver is preferable to the general purpose SliverPersistentHeader for its relatively narrow use case because there's no need to create a SliverPersistentHeaderDelegate or to predict the header's size.

Screen.Recording.2024-07-02.at.9.03.23.AM.mov

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels Jul 1, 2024
@HansMuller HansMuller force-pushed the floating_header_sliver branch 2 times, most recently from 6533bfb to dbc7208 Compare July 2, 2024 16:27
@github-actions github-actions bot added d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos labels Jul 2, 2024
@HansMuller HansMuller requested a review from QuncCccccc July 2, 2024 16:30
@HansMuller HansMuller force-pushed the floating_header_sliver branch from 7e8a98a to 92cd153 Compare July 2, 2024 21:17
Copy link
Contributor

@QuncCccccc QuncCccccc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this looks good to me! Just left some nits and questions:)

/// [SliverPersistentHeaderDelegate] or to predict the header's size.
///
/// {@tool dartpad}
/// This example shows how to create a SliverFloatingHeader.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// This example shows how to create a SliverFloatingHeader.
/// This example shows how to create a [SliverFloatingHeader].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

final ColorScheme colorScheme = theme.colorScheme;

return Container(
color: colorScheme.background,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ColorScheme.background is deprecated, ColorScheme.surface can be used to replace it:)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

/// configured as a pinned, resizing, or floating header.
class SliverFloatingHeader extends StatefulWidget {
/// Create a floating header sliver that animates into view when the user
/// scrolls forward, and disappears the user starts scrolling in the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// scrolls forward, and disappears the user starts scrolling in the
/// scrolls forward, and disappears when the user starts scrolling in the

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

});

/// Non null properties override the default durations (300ms) and
/// curves (Curves.easeInOut) for subsequent header animations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// curves (Curves.easeInOut) for subsequent header animations.
/// curves ([Curves.easeInOut]) for subsequent header animations.

}

class _SliverFloatingHeaderState extends State<SliverFloatingHeader> with SingleTickerProviderStateMixin {
ScrollPosition? position;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that position is not used anywhere in this class, maybe we can remove it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YES. Thanks for catching that!

AnimationController? snapController;
double? lastScrollOffset;

// The distance from the start of the header to the start of the viewport. Whent the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The distance from the start of the header to the start of the viewport. Whent the
// The distance from the start of the header to the start of the viewport. When the

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


// The distance from the start of the header to the start of the viewport. Whent the
// header is showing it varies between 0 (completely visible) and childExtent (not visible
// because it's just abopve the viewport's starting edge). It's used to compute the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// because it's just abopve the viewport's starting edge). It's used to compute the
// because it's just above the viewport's starting edge). It's used to compute the

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

super.detach();
}

// True if the header has been laid at at least once (lastScrollOffset != null) and either:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// True if the header has been laid at at least once (lastScrollOffset != null) and either:
// True if the header has been laid out at least once (lastScrollOffset != null) and either:

Comment on lines +267 to +268
final double paintExtent = childExtent - effectiveScrollOffset;
final double layoutExtent = childExtent - constraints.scrollOffset;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these two be the same value childExtent - effectiveScrollOffset?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, although that would cause slightly different behavior when the header animated in our out. If paintExtent and layoutExtent were the same then the list would appear to scroll up or down when the header snapped in or out of view. That's a useful alternative (that's the way the Instagram floating header works) although it's not the same way that the existing floating SliverPersistentHeader works.

It would be easy enough to make this an option although, if it's OK with you, I'll do that in a separate PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah got it! I agree to be consistent with SliverPersistentHeader:) Thanks for the explanation!

Copy link
Contributor

@QuncCccccc QuncCccccc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Sorry I spent a little longer time to review this PR. It took me some time to understand the paint() method in AxisDirection.up and AxisDirection.left conditions:)

@HansMuller HansMuller force-pushed the floating_header_sliver branch from 6873abd to 608cc08 Compare July 3, 2024 18:27
@github-actions github-actions bot added the f: focus Focus traversal, gaining or losing focus label Jul 3, 2024
@HansMuller
Copy link
Contributor Author

This PR includes a temporary workaround for dart-lang/sdk#56129 in focus_manager.dart:

String debugDescribeFocusTree() {
  String? result;
  assert(() {
    // TODO(yjbanov): remove this once https://github.com/dart-lang/sdk/issues/56129 has been fixed.
    // ignore: unnecessary_statements
    FocusManager.instance.toStringDeep;
    result = FocusManager.instance.toStringDeep();
    return true;
  }());

@HansMuller HansMuller added autosubmit Merge PR when tree becomes green via auto submit App labels Jul 3, 2024
@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jul 3, 2024
@auto-submit
Copy link
Contributor

auto-submit bot commented Jul 3, 2024

auto label is removed for flutter/flutter/151145, due to - The status or check suite Mac_arm64 build_tests_2_4 has failed. Please fix the issues identified (or deflake) before re-applying this label.

@HansMuller HansMuller added the autosubmit Merge PR when tree becomes green via auto submit App label Jul 3, 2024
@auto-submit auto-submit bot merged commit d1e1500 into flutter:master Jul 3, 2024
@HansMuller HansMuller deleted the floating_header_sliver branch July 3, 2024 20:07
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 5, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 5, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Jul 7, 2024
Roll Flutter from af913a7 to fafd67d (41 revisions)

flutter/flutter@af913a7...fafd67d

2024-07-05 [email protected] Roll Flutter Engine from 74d40c160e48 to 4ee09d3b7f3b (1 revision) (flutter/flutter#151346)
2024-07-05 [email protected] Roll Flutter Engine from ba9c7b6336ef to 74d40c160e48 (1 revision) (flutter/flutter#151340)
2024-07-05 [email protected] Roll Flutter Engine from 1f0f950ea02a to ba9c7b6336ef (1 revision) (flutter/flutter#151331)
2024-07-05 [email protected] Roll Flutter Engine from 3c6a373bda3e to 1f0f950ea02a (1 revision) (flutter/flutter#151326)
2024-07-04 [email protected] Roll Flutter Engine from 79a91e38c587 to 3c6a373bda3e (2 revisions) (flutter/flutter#151318)
2024-07-04 [email protected] Roll Packages from d2705fb to 754de19 (3 revisions) (flutter/flutter#151315)
2024-07-04 [email protected] Roll Flutter Engine from 2b6bb516e7e6 to 79a91e38c587 (2 revisions) (flutter/flutter#151314)
2024-07-04 [email protected] Roll Flutter Engine from 8e2d05fa95d7 to 2b6bb516e7e6 (2 revisions) (flutter/flutter#151299)
2024-07-04 [email protected] Roll Flutter Engine from 4190543cb093 to 8e2d05fa95d7 (13 revisions) (flutter/flutter#151293)
2024-07-03 [email protected] Roll pub packages (flutter/flutter#151203)
2024-07-03 [email protected] Fix invalid URL suggestion for gradle incompatability (flutter/flutter#150999)
2024-07-03 [email protected] Cupertino transparent navigation bars (flutter/flutter#149102)
2024-07-03 [email protected] Prepares semantics_update_test for upcoming link URL change (flutter/flutter#151261)
2024-07-03 [email protected] Add a message about spam/brigading (flutter/flutter#150583)
2024-07-03 [email protected] PinnedHeaderSliver example based on the iOS Settings AppBar (flutter/flutter#151205)
2024-07-03 [email protected] Update deprecation policy (flutter/flutter#151257)
2024-07-03 [email protected] SliverFloatingHeader (flutter/flutter#151145)
2024-07-03 [email protected] Remove warning when KGP version not detected (flutter/flutter#151254)
2024-07-03 [email protected] Feat: Add withOpacity to gradient (flutter/flutter#150670)
2024-07-03 [email protected] Fix references in examples (flutter/flutter#151204)
2024-07-03 [email protected] Fix link in tree hygene doc (flutter/flutter#151235)
2024-07-03 [email protected] content dimensions are not established get controller value error (flutter/flutter#148938)
2024-07-03 [email protected] chore: fix typos and link broken (flutter/flutter#150402)
2024-07-03 [email protected] Add example of goldenFileComparator usage in widget tests (flutter/flutter#150422)
2024-07-03 [email protected] Fix project name fallback (flutter/flutter#150614)
2024-07-03 [email protected] Roll Flutter Engine from a3e61c0fd1c2 to 4190543cb093 (1 revision) (flutter/flutter#151241)
2024-07-03 [email protected] Roll Flutter Engine from 8274f54f11be to a3e61c0fd1c2 (2 revisions) (flutter/flutter#151237)
2024-07-03 [email protected] Force regeneration of platform-specific manifests before running performance tests (flutter/flutter#151003)
2024-07-03 [email protected] Handle a SocketException thrown when sending the browser close command to Chrome (flutter/flutter#151197)
2024-07-03 [email protected] Roll Flutter Engine from a02e3f673da3 to 8274f54f11be (4 revisions) (flutter/flutter#151226)
2024-07-03 [email protected] Roll Flutter Engine from c5c0c54d6d1d to a02e3f673da3 (1 revision) (flutter/flutter#151212)
2024-07-03 [email protected] Roll Flutter Engine from 44278941443e to c5c0c54d6d1d (9 revisions) (flutter/flutter#151208)
2024-07-02 [email protected] Fix scheduler event loop being stuck due to task with Priority.idle (flutter/flutter#151168)
2024-07-02 [email protected] Fix result propagation in RenderSliverEdgeInsetsPadding.hitTestChildren (flutter/flutter#149825)
2024-07-02 [email protected] docImports for flutter_test (flutter/flutter#151189)
2024-07-02 [email protected] Interactable ScrollView content when settling a scroll activity (flutter/flutter#145848)
2024-07-02 [email protected] [flutter_tools] Update the mapping for the Dart SDK internal URI (flutter/flutter#151170)
2024-07-02 [email protected] Roll pub packages (flutter/flutter#151129)
2024-07-02 [email protected] Fix typo (flutter/flutter#151192)
2024-07-02 [email protected] [tool] Fix `stdin.flush` calls on processes started by `FakeProcessManager` (flutter/flutter#151183)
2024-07-02 [email protected] Roll Flutter Engine from 433d360eee11 to 44278941443e (4 revisions) (flutter/flutter#151186)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human
...
victorsanni pushed a commit to victorsanni/flutter that referenced this pull request Jul 8, 2024
A sliver that shows its [child] when the user scrolls forward and hides it when the user scrolls backwards. Similar headers can be found in  Google Photos and Facebook.

This sliver is preferable to the general purpose SliverPersistentHeader for its relatively narrow use case because there's no need to create a SliverPersistentHeaderDelegate or to predict the header's size.

https://github.com/flutter/flutter/assets/1377460/82b67dfb-5d38-4adf-9415-fc8527d0eb9f
@k-ane
Copy link

k-ane commented Sep 13, 2024

Hi @HansMuller I found a tiny bug here where I believe min() is being used instead of max()

CleanShot 2024-09-13 at 15 34 05@2x

This causes the following behaviour

CleanShot.2024-09-13.at.15.19.55.mp4

From a quick test on my machine just changing to max so that the overlap is used fixes the issue :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: focus Focus traversal, gaining or losing focus f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants