Skip to content

Conversation

@QuncCccccc
Copy link
Contributor

This PR is to create Carousel.weighted so the size of each carousel item is based on a list of weights. While scrolling, item sizes are changing dynamically based on the scrolling progress.

weighted_carousel.mov

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos labels Jun 5, 2024
@QuncCccccc QuncCccccc force-pushed the carousel_p2 branch 2 times, most recently from c076d7f to d3efad5 Compare June 7, 2024 20:16
@QuncCccccc QuncCccccc marked this pull request as ready for review June 10, 2024 22:56
@QuncCccccc
Copy link
Contributor Author

Since Hans came back, I also added him as a reviewer😁

@bogdanenedoghitoiu

This comment was marked as outdated.

@Piinks
Copy link
Contributor

Piinks commented Jun 20, 2024

Could you please add a `final ScrollBehavior?

ScrollBehavior is already inherited by the internal scrollable widget. You should be able to configure this by adding a ScrollConfiguration above the carousel. We usually only expose a scrollBehavior property if the widget is overriding it internally for a specific feature, making it inaccessible without exposing it as a property. I don't know that we need to do that in this case.

@bogdanenedoghitoiu
Copy link

Could you please add a `final ScrollBehavior?

ScrollBehavior is already inherited by the internal scrollable widget. You should be able to configure this by adding a ScrollConfiguration above the carousel. We usually only expose a scrollBehavior property if the widget is overriding it internally for a specific feature, making it inaccessible without exposing it as a property. I don't know that we need to do that in this case.

That makes sense, I will try it like this. Thank you for the reply!

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

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

This is coming along so nicely! Mostly nits and a couple of questions. Thanks for your patience!

/// enables dynamic item sizing. Each item is assigned a weight that determines
/// the portion of the viewport it occupies. This allows you to easily create
/// layouts like multi-browse, and hero. In order to have a full-screen layout,
/// if [CarouselView] is used, then set the [itemExtent] to screen size; if
Copy link
Contributor

Choose a reason for hiding this comment

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

The viewport won't necessarily be the full screen size, it could be part of a column with other elements, or under an app bar in a Scaffold. How would someone determine the size of the viewport in order to set itemExtent? This might be a good example to include.

/// As the initially visible items change size during scrolling, item 3 enters
/// the view to fill the remaining space. Its extent starts at a minimum of
/// [shrinkExtent] (or 0 if [shrinkExtent] is not provided) and gradually
/// increases to match the extent of the last visible item (100 in this example).
Copy link
Contributor

Choose a reason for hiding this comment

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

These docs are super valuable! But they will not be on https://api.flutter.dev/ since this is a private class. Should we move these docs up to the public class?

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, I can move these docs to the public CarouselView class! Is this okay if we include these calculation explanation in public doc?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I think it is fine to include! :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated!

Comment on lines +950 to +969
// This method is mostly the same as its parent class [RenderSliverFixedExtentList].
// The difference is when we allow some space before the leading items or after
// the trailing items with smaller weights, we leave extra scroll offset.
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than copying most of this logic, can we add a spacing value/getter/method on the super class? If this is feasible, we could do it in a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good to me! Added a TODO here:)

@QuncCccccc QuncCccccc force-pushed the carousel_p2 branch 3 times, most recently from 7a88cee to 866ad31 Compare July 1, 2024 22:10
@QuncCccccc QuncCccccc requested a review from Piinks July 1, 2024 22:50
/// Scaffold(
/// body: CarouselView(
/// scrollDirection: Axis.vertical,
/// itemExtent: MediaQuery.sizeOf(context).height,
Copy link
Contributor

Choose a reason for hiding this comment

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

This would be the size of the device screen, not necessarily the size of the CarouselView. What if the carousel is smaller than the device screen?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To make the itemExtent match the size of the carousel, we can use double.infinity. Just updated the sample code:)!

class _CarouselViewState extends State<CarouselView> {
late double _itemExtent;
double? _itemExtent;
List<int>? _weights;
Copy link
Member

Choose a reason for hiding this comment

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

The whole purpose for this is when the initial item is given some value, we know how the initial view should look like.

Is this only used for initialization? Do we need to tell the controller (i.e. in didUpdateWidget) when these values have changed on the widget so the controller can redo its calculations with the new values?

(Instead copying I would also lean toward getters, the other question as to whether we need to tell the controller when these values change still stands, though)

Comment on lines 309 to 310
_consumeMaxWeight = widget.consumeMaxWeight;
_itemExtent = widget.itemExtent;
Copy link
Member

Choose a reason for hiding this comment

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

Why copy these in didChangeDependencies, but _weights is copied in initState?

final double? itemExtent = _carouselState!._itemExtent;
int expandedItem = initialItem;

if (weights != null && !_carouselState!._consumeMaxWeight) {
Copy link
Member

Choose a reason for hiding this comment

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

Related to the above question: What if the values read from _carouselState change after they have been read? Do we need to inform the controller and redo some of these calculations? Would also be good to add a test for that case.

Copy link
Contributor

Choose a reason for hiding this comment

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

We've been chatting about this. I think what is needed here is to update the position, not the controller. The values provided to the controller are just passed to (and only used by) the position, which calculates what item is at what pixel, or what pixel is at which item based on those values.
So if they change here, we should update _controller.position.VALUE so it can make the right calculations based on the new info.

Converting the properties in the carousel scroll position to setters/getters will make this possible, with an update to the pixels when the value changes. (See _PagePosition.viewportFraction). And thanks Qun for mentioning PageView, looking at that really helped!

What do you all think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This makes sense to me:) Trying to add setters and getters for itemExtent and flexWeights in _CarouselPosition and setting they to new values when they are updated. Thanks for the suggestions!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just updated! _flexWeights and _consumeMaxWeight are changed to getters in _CarouselViewState class. _itemExtent should be constrained to be smaller than the viewport in the implementation, so I keep it as is.

And when we update flexWeights, the layout will change to match the new weight list but the item that occupies the max weight stays the same. When we update itemExtent, the item main-axis extent will change but leading item also stays the same.

Demo 1 (Updating weights respects `initialItem`)
update_weights.mov
Demo 2 (Updating weights respects the item that currently occupied the max weight)
current_max_item.mov

@QuncCccccc QuncCccccc force-pushed the carousel_p2 branch 2 times, most recently from 6c3db4c to dd98db8 Compare July 9, 2024 18:14
@QuncCccccc QuncCccccc requested review from Piinks and goderbauer July 9, 2024 22:07
Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

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

Flutter_LGTM

engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 18, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 18, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 18, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 18, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 18, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 18, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 19, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 19, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 19, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 19, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 19, 2024
LouiseHsu pushed a commit to flutter/packages that referenced this pull request Jul 20, 2024
Roll Flutter from 58068d8 to 7d5c1c0 (104 revisions)

flutter/flutter@58068d8...7d5c1c0

2024-07-19 [email protected] Enhances
intuitiveness of RawMagnifier's example (flutter/flutter#150308)
2024-07-19 [email protected]
Roll pub packages (flutter/flutter#151992)
2024-07-19 [email protected] Add test for
scrollbar.1.dart (flutter/flutter#151463)
2024-07-19 [email protected] Roll Flutter Engine from
ea1e53a4e810 to 969fb7abc449 (3 revisions) (flutter/flutter#152018)
2024-07-19 [email protected] docimports for rendering library
(flutter/flutter#151958)
2024-07-19 [email protected] Roll Flutter Engine from
b65c93ea948e to ea1e53a4e810 (2 revisions) (flutter/flutter#152012)
2024-07-19 [email protected] painting: drop deprecated
(exported) hashList and hashValues functions (flutter/flutter#151677)
2024-07-18 [email protected] Roll Flutter Engine from
766f7bed7185 to b65c93ea948e (2 revisions) (flutter/flutter#152004)
2024-07-18 [email protected] Update TESTOWNERS (flutter/flutter#151907)
2024-07-18 [email protected] chore: fix test name & add description of
tests (flutter/flutter#151959)
2024-07-18 [email protected] Roll Flutter Engine from
564ded4c4742 to 766f7bed7185 (2 revisions) (flutter/flutter#151998)
2024-07-18 [email protected] Fix SelectionArea scrolling
conflicts (flutter/flutter#151138)
2024-07-18 [email protected] Fix:
BaseTapAndDragGestureRecognizer should reset drag state after losing
gesture arena (flutter/flutter#151989)
2024-07-18 [email protected]
Roll pub packages (flutter/flutter#151975)
2024-07-18 [email protected] Roll Flutter Engine from
8bcf638eb893 to 564ded4c4742 (2 revisions) (flutter/flutter#151986)
2024-07-18 [email protected] Fix
WidgetStateTextStyle's doc (flutter/flutter#151935)
2024-07-18 [email protected] Roll Flutter Engine from
d58ba74250ce to 8bcf638eb893 (2 revisions) (flutter/flutter#151977)
2024-07-18 [email protected] Adds 3.22.3 changelog
(flutter/flutter#151974)
2024-07-18 [email protected] Roll Packages from
d03b1b4 to c7f0526 (8 revisions) (flutter/flutter#151971)
2024-07-18 [email protected] `WidgetState` mapping
(flutter/flutter#146043)
2024-07-18 [email protected] Fix AppBar doc to keep diagram next to its
description (flutter/flutter#151937)
2024-07-18 [email protected] Small fixes to Image docs: NNBD, and add a
cross-reference (flutter/flutter#151938)
2024-07-18 [email protected] Roll Flutter Engine from
b043fe447bb3 to d58ba74250ce (1 revision) (flutter/flutter#151964)
2024-07-18 [email protected]
Roll pub packages (flutter/flutter#151946)
2024-07-18 [email protected]
Roll pub packages (flutter/flutter#151904)
2024-07-18 [email protected] Roll Flutter Engine from
e3abca2d8105 to b043fe447bb3 (1 revision) (flutter/flutter#151942)
2024-07-18 [email protected] Roll Flutter Engine from
8073523b4623 to e3abca2d8105 (1 revision) (flutter/flutter#151936)
2024-07-18 [email protected] Roll Flutter Engine from
dfe22e3acc19 to 8073523b4623 (1 revision) (flutter/flutter#151934)
2024-07-18 [email protected] Roll Flutter Engine from
184c3f0de6b3 to dfe22e3acc19 (1 revision) (flutter/flutter#151930)
2024-07-18 [email protected] Roll Flutter Engine from
00f0f6b74da7 to 184c3f0de6b3 (1 revision) (flutter/flutter#151928)
2024-07-18 [email protected] Roll Flutter Engine from
d194a2f0e5da to 00f0f6b74da7 (1 revision) (flutter/flutter#151927)
2024-07-18 [email protected] Roll Flutter Engine from
a5a93bb80bd1 to d194a2f0e5da (3 revisions) (flutter/flutter#151925)
2024-07-17 [email protected] Roll Flutter Engine from
e9dc62074c2b to a5a93bb80bd1 (1 revision) (flutter/flutter#151918)
2024-07-17 [email protected] [web] use the new backlog Github project
in triage links (flutter/flutter#151920)
2024-07-17 [email protected] Update Flutter-Web-Triage.md
(flutter/flutter#151607)
2024-07-17 [email protected] Reland fix InputDecorator hint default
text style on M3 (flutter/flutter#150835)
2024-07-17 [email protected] Roll Flutter Engine from
39ee1a549581 to e9dc62074c2b (3 revisions) (flutter/flutter#151915)
2024-07-17 [email protected] Constrain `CupertinoContextMenu`
animation to safe area (flutter/flutter#151860)
2024-07-17 [email protected] Create
`CarouselView` widget - Part 2 (flutter/flutter#149775)
2024-07-17 [email protected] Roll Flutter Engine from
45b722b661f0 to 39ee1a549581 (3 revisions) (flutter/flutter#151905)
2024-07-17 [email protected] docs: Fix typo
in data driven fixes test folder section (flutter/flutter#151836)
2024-07-17 [email protected] Stop running flaky mac
tests in presubmit (flutter/flutter#151870)
2024-07-17 [email protected] Roll Flutter Engine from
7e2579634027 to 45b722b661f0 (1 revision) (flutter/flutter#151895)
2024-07-17 [email protected] fix(Flutter Web
App): fixes html lang typo (flutter/flutter#151866)
2024-07-17 [email protected] Delete `docs/engine`
directory (flutter/flutter#151616)
2024-07-17 [email protected] Make
`CupertinoSlidingSegmentedControl` type parameter non-null
(flutter/flutter#151803)
...
@nguyenthanhphap1413
Copy link

Hi @QuncCccccc Hi, how can I get the index of the currently displayed items? Suppose I pass List? _weights = [6,1], how can I get the index when I scroll to the positions?. Even the index of the position corresponding to 6 would be fine. Is there a way to get it or a formula to calculate it?

TytaniumDev pushed a commit to TytaniumDev/flutter that referenced this pull request Aug 7, 2024
This PR is to create `Carousel.weighted` so the size of each carousel item is based on a list of weights. While scrolling, item sizes are changing dynamically based on the scrolling progress.

https://github.com/flutter/flutter/assets/36861262/181472b0-6f8b-48e7-b191-ab5f7c88c0c8
@bharathwajv
Copy link

can you please add options like this

CarouselOptions(
autoPlay: true,
enlargeCenterPage: true,
aspectRatio: 2.0,
),

@MarkOSullivan94
Copy link
Contributor

MarkOSullivan94 commented Aug 11, 2024

What version of Flutter will have this? I noticed it's not in 3.24.0

@deminearchiver
Copy link

My wild guess is 3.26 stable, but it's already available on the main channel

@Piinks
Copy link
Contributor

Piinks commented Aug 12, 2024

Hi everyone. The team (usually) does not follow up on comments in closed PRs. Please open a new issue for bugs, see where's my commit for what build tag is on a given PR, or see the help channel on Discord for questions.

@flutter flutter locked as off-topic and limited conversation to collaborators Aug 12, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

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: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants