5 Commits

Author SHA1 Message Date
Kate Lovett
9d96df2364
Modernize framework lints (#179089)
WIP

Commits separated as follows:
- Update lints in analysis_options files
- Run `dart fix --apply`
- Clean up leftover analysis issues 
- Run `dart format .` in the right places.

Local analysis and testing passes. Checking CI now.

Part of https://github.com/flutter/flutter/issues/178827
- Adoption of flutter_lints in examples/api coming in a separate change
(cc @loic-sharma)

## 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.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-11-26 01:10:39 +00:00
Tong Mu
cc35800e6a
Fix SpringSimulation formula for underdamping (#165017)
Fix https://github.com/flutter/flutter/issues/163858

## 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.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-03-21 20:46:07 +00:00
Bernardo Ferrari
b35c6be8c9
Add withDurationAndBounce to SpringDescription (#164411)
Part of https://github.com/flutter/flutter/issues/152587

###  Description:
With `withDurationAndBounce` (we could also rename to `withDuration`),
the user only has to worry about a single attribute: the bounce (and
duration, but they would have to worry with duration anyway. If they
don't, there is a default value already). The standard
`SpringDescription` has 3 values, so it is way more abstract. This
should help a lot people to make beautiful spring animations using
Flutter.

<img width="838" alt="image"
src="https://github.com/user-attachments/assets/4d0dccc7-0f97-4a13-99a4-268228b87f08"
/>

### Negative bounce:

I didn't enable bounce to be negative because the behavior is super
tricky. I don't know what formula Apple is using, but seems like it is
not public. There are many different formulas we can use, including the
one provided on the original issue, but then there is the risk of people
complaining it works differently than SwiftUI. I need to check if other
projects (react-spring, framer motion) support negative bounce, but
feels like this is something 99.9999% of people wouldn't expect or use,
so I think we are safe. I couldn't find a single usage of negative
bounce on Swift in all GitHub (without a duration, using code-search, vs
5k cases with positive values). Not even sure the todo is needed, but
won't hurt.


### Comparison

<details>
  <summary>Dart vs Swift testing results</summary>

```dart
 testWidgets('Spring Simulation Tests - Matching SwiftUI', (WidgetTester tester) async {
      // Test cases matching the Swift code's ranges
      List<({Duration duration, double bounce})> testCases = [
        (duration: const Duration(milliseconds: 100), bounce: 0.0),
        (duration: const Duration(milliseconds: 100), bounce: 0.3),
        (duration: const Duration(milliseconds: 100), bounce: 0.8),
        (duration: const Duration(milliseconds: 100), bounce: 1.0),
        (duration: const Duration(milliseconds: 500), bounce: 0.0),
        (duration: const Duration(milliseconds: 500), bounce: 0.3),
        (duration: const Duration(milliseconds: 500), bounce: 0.8),
        (duration: const Duration(milliseconds: 500), bounce: 1.0),
        (duration: const Duration(milliseconds: 1000), bounce: 0.0),
        (duration: const Duration(milliseconds: 1000), bounce: 0.3),
        (duration: const Duration(milliseconds: 1000), bounce: 0.8),
        (duration: const Duration(milliseconds: 1000), bounce: 1.0),
        (duration: const Duration(milliseconds: 2000), bounce: 0.0),
        (duration: const Duration(milliseconds: 2000), bounce: 0.3),
        (duration: const Duration(milliseconds: 2000), bounce: 0.8),
        (duration: const Duration(milliseconds: 2000), bounce: 1.0),
      ];

      for (final testCase in testCases) {
        SpringDescription springDesc = SpringDescription.withDurationAndBounce(
          duration: testCase.duration,
          bounce: testCase.bounce,
        );

        print(
          'Duration: ${testCase.duration.inMilliseconds / 1000}, Bounce: ${testCase.bounce}, Mass: ${springDesc.mass}, Stiffness: ${springDesc.stiffness}, Damping: ${springDesc.damping}',
        );
      }
    });
```
Output:
```
Duration: 0.1, Bounce: 0.0, Mass: 1.0, Stiffness: 3947.8417604357423, Damping: 125.66370614359171
Duration: 0.1, Bounce: 0.3, Mass: 1.0, Stiffness: 3947.8417604357423, Damping: 87.9645943005142
Duration: 0.1, Bounce: 0.8, Mass: 1.0, Stiffness: 3947.8417604357423, Damping: 25.132741228718338
Duration: 0.1, Bounce: 1.0, Mass: 1.0, Stiffness: 3947.8417604357423, Damping: 0.0
Duration: 0.5, Bounce: 0.0, Mass: 1.0, Stiffness: 157.91367041742973, Damping: 25.132741228718345
Duration: 0.5, Bounce: 0.3, Mass: 1.0, Stiffness: 157.91367041742973, Damping: 17.59291886010284
Duration: 0.5, Bounce: 0.8, Mass: 1.0, Stiffness: 157.91367041742973, Damping: 5.026548245743668
Duration: 0.5, Bounce: 1.0, Mass: 1.0, Stiffness: 157.91367041742973, Damping: 0.0
Duration: 1.0, Bounce: 0.0, Mass: 1.0, Stiffness: 39.47841760435743, Damping: 12.566370614359172
Duration: 1.0, Bounce: 0.3, Mass: 1.0, Stiffness: 39.47841760435743, Damping: 8.79645943005142
Duration: 1.0, Bounce: 0.8, Mass: 1.0, Stiffness: 39.47841760435743, Damping: 2.513274122871834
Duration: 1.0, Bounce: 1.0, Mass: 1.0, Stiffness: 39.47841760435743, Damping: 0.0
Duration: 2.0, Bounce: 0.0, Mass: 1.0, Stiffness: 9.869604401089358, Damping: 6.283185307179586
Duration: 2.0, Bounce: 0.3, Mass: 1.0, Stiffness: 9.869604401089358, Damping: 4.39822971502571
Duration: 2.0, Bounce: 0.8, Mass: 1.0, Stiffness: 9.869604401089358, Damping: 1.256637061435917
Duration: 2.0, Bounce: 1.0, Mass: 1.0, Stiffness: 9.869604401089358, Damping: 0.0
```

Swift:
```swift
import SwiftUI
import XCTest

class SpringParameterTests: XCTestCase {

    func printSpringParameters(duration: Double, bounce: Double) {
        let spring = Spring(duration: duration, bounce: bounce) // Let SwiftUI do its thing
        print("Duration: \(duration), Bounce: \(bounce), Mass: \(spring.mass), Stiffness: \(spring.stiffness), Damping: \(spring.damping)")
    }

    func testParameterExtraction() {
        // Test a range of durations and bounces
        let durations: [Double] = [0.1, 0.5, 1.0, 2.0]
        let bounces: [Double] = [0.0, 0.3, 0.8, 1.0]

        for duration in durations {
            for bounce in bounces {
                printSpringParameters(duration: duration, bounce: bounce)
            }
        }
    }
}
```
Output:
```
Duration: 0.1, Bounce: 0.0, Mass: 1.0, Stiffness: 3947.8417604357433, Damping: 125.66370614359172
Duration: 0.1, Bounce: 0.3, Mass: 1.0, Stiffness: 3947.841760435743, Damping: 87.96459430051421
Duration: 0.1, Bounce: 0.8, Mass: 1.0, Stiffness: 3947.8417604357423, Damping: 25.132741228718338
Duration: 0.1, Bounce: 1.0, Mass: 1.0, Stiffness: 3947.8417604357433, Damping: 0.0
Duration: 0.5, Bounce: 0.0, Mass: 1.0, Stiffness: 157.91367041742973, Damping: 25.132741228718345
Duration: 0.5, Bounce: 0.3, Mass: 1.0, Stiffness: 157.9136704174297, Damping: 17.59291886010284
Duration: 0.5, Bounce: 0.8, Mass: 1.0, Stiffness: 157.9136704174297, Damping: 5.026548245743668
Duration: 0.5, Bounce: 1.0, Mass: 1.0, Stiffness: 157.91367041742973, Damping: 0.0
Duration: 1.0, Bounce: 0.0, Mass: 1.0, Stiffness: 39.47841760435743, Damping: 12.566370614359172
Duration: 1.0, Bounce: 0.3, Mass: 1.0, Stiffness: 39.478417604357425, Damping: 8.79645943005142
Duration: 1.0, Bounce: 0.8, Mass: 1.0, Stiffness: 39.478417604357425, Damping: 2.513274122871834
Duration: 1.0, Bounce: 1.0, Mass: 1.0, Stiffness: 39.47841760435743, Damping: 0.0
Duration: 2.0, Bounce: 0.0, Mass: 1.0, Stiffness: 9.869604401089358, Damping: 6.283185307179586
Duration: 2.0, Bounce: 0.3, Mass: 1.0, Stiffness: 9.869604401089356, Damping: 4.39822971502571
Duration: 2.0, Bounce: 0.8, Mass: 1.0, Stiffness: 9.869604401089356, Damping: 1.256637061435917
Duration: 2.0, Bounce: 1.0, Mass: 1.0, Stiffness: 9.869604401089358, Damping: 0.0
```
There are minor differences which should be rounding errors.

</details>
2025-03-11 07:44:29 +00:00
Michael Goderbauer
5491c8c146
Auto-format Framework (#160545)
This auto-formats all *.dart files in the repository outside of the
`engine` subdirectory and enforces that these files stay formatted with
a presubmit check.

**Reviewers:** Please carefully review all the commits except for the
one titled "formatted". The "formatted" commit was auto-generated by
running `dev/tools/format.sh -a -f`. The other commits were hand-crafted
to prepare the repo for the formatting change. I recommend reviewing the
commits one-by-one via the "Commits" tab and avoiding Github's "Files
changed" tab as it will likely slow down your browser because of the
size of this PR.

---------

Co-authored-by: Kate Lovett <katelovett@google.com>
Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
2024-12-19 20:06:21 +00:00
Tong Mu
c16aa2d232
Make animation and router support simulation, and use Spring for Cupertino (#155575)
This PR makes `TransitionRoute` support driving the animation with
`Simulation`. This is needed for Cupertino widgets, since iOS use
"spring simulations" for a majority of their animations.

This PR also applies the standard spring animation to
`CupertinoDialogRoute` (alert dialogs) and `CupertinoModalPopupRoute`
(action sheets). (This PR does not yet support customizing the spring
parameters or conveniently using the springs for custom routes, which
are left for future PRs.)

### Comparison

I tried to create a comparison video for action sheets, however the
difference is far less noticeable than I expected. (All clips are
precisely aligned at the moment the pointer is lifted.) I guess the
original curve _is_ good enough. Nevertheless, the spring simulation is
the correct one and we should support it.

Edit: [The
comment](https://github.com/flutter/flutter/pull/155575#issuecomment-2489303282)
below also mentioned that supporting spring animation will improve the
fidelity when the animation is caused by a user gesture. I assume this
requires initial speed, which is not supported by this PR but we can add
it in the future.


https://github.com/user-attachments/assets/06d2f684-ad1c-4a4d-8663-a561895f45e9

Also, Flutter's response seems to be always a moment slower than
SwiftUI, possibly because Flutter requiring two frames to start the
animation (one frame to add the transition widget, one frame for the
animation to actually progress.) We probably want to solve it in the
future.

## 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.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2024-12-12 21:56:11 +00:00