Skip to content

[tabs_overlay] Migrate to material_ui - #239

Draft
pjkammer wants to merge 9 commits into
flutter:mainfrom
pjkammer:tabs-overlay-material-ui
Draft

pjkammer wants to merge 9 commits into
flutter:mainfrom
pjkammer:tabs-overlay-material-ui

Conversation

@pjkammer

@pjkammer pjkammer commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

DRAFT

**Stacked on #237.** Until it merges, this PR also shows #237's 7 commits. Only the last 2 are this PR's: [view just those changes](https://github.com/flutter/platform_tests/pull/239/files/9319b19c888ea57b422c2b8392580786b61bd630..81b453a57604dad3baf94e9323ce1212b55a063a).

Migrates tabs_overlay from package:flutter/material.dart to package:material_ui/material_ui.dart, where the Material widgets are developed now, so the app compares the platform's tab view with the TabBarView the team works on.

Commits, both unmodified tool output:

  1. Add the dependency. flutter pub add material_ui, which adds material_ui: ^1.7.0. material_ui requires Flutter 3.47.
  2. Switch the import. dart fix --apply --code=migrate_design_widgets switches lib/main.dart, the only file that imported material.dart.

Appearance on an iPhone 17 Pro simulator (iOS 26.4) and a Pixel 8 emulator (Android 17) is the same before and after the change. Each pair of recordings below replays the same scripted gestures before and after.

iOS, swiping to tab 2 and back:

BeforeAfter
ios_before.mp4
ios_after.mp4

Android, tapping the native TAB 2 and swiping back:

BeforeAfter
android_before.mp4
android_after.mp4

Tested with Flutter 3.47.7: flutter analyze, flutter test and dart format are clean, no package:flutter/material.dart import is left, and the integration test passes on both devices.

Part of flutter/flutter#172942

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 the Flutter Style Guide recently, and have followed its advice.
  • 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.
    The existing widget and integration smoke tests cover the change: both run the app, which now builds its tabs from material_ui.
  • All existing and new tests are passing.
    No CI runs tests here. Locally, flutter test passes, and the integration test passes on iOS and Android.

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

1. Copied analysis_options.yaml from `flutter create` (Flutter 3.47.7).
   (Adds analyzer excludes and updates lint doc link)
2. Updated pubspec.yaml to
   - Raise SDK constraint to ^3.13.0 to match material_ui.
   - Remove unused cupertino_icons.
3. flutter pub upgrade --major-versions
   - raises flutter_lints from ^2.0.3 to ^6.0.0
   - archive 3.3.2 is no longer a dependency,
     which resolves GHSA-9v85-q87q-g4vg and GHSA-r285-q736-9v95
Identified with `flutter analyze` and updated with
`dart fix --apply --code=use_super_parameters`
Generated with `dart format` (Dart 3.13.5)
Generated by `flutter build ios --simulator --debug` on Flutter 3.47.7

No hand edits. Tool output:
```
Resolving dependencies...
Downloading packages...
  material_color_utilities 0.13.0 (0.13.1 available)
  test_api 0.7.12 (0.7.15 available)
Got dependencies!
2 packages have newer versions incompatible with dependency constraints.
Try `flutter pub outdated` for more information.
Building com.example.tabsOverlay for simulator (ios)...
Updating minimum iOS deployment target to 15.0.
Upgrading project.pbxproj
Upgrading AppFrameworkInfo.plist
Updating project for Xcode compatibility.
Upgrading project.pbxproj
Upgrading Runner.xcscheme
Upgrading Info.plist
Removing script build phase dependency analysis.
Adding input path to Thin Binary build phase.
ios/Runner/AppDelegate.swift uses the deprecated @UIApplicationMain attribute, updating.
Adding Swift Package Manager integration...                         4.4s
Upgrading Runner.xcscheme
To ensure your app continues to launch on upcoming iOS versions, UIScene lifecycle support will soon be required. Please see https://flutter.dev/to/uiscene-migration for the migration guide.

Running Xcode build...
Xcode build done.                                           20.2s
✓ Built build/ios/iphonesimulator/Runner.app
```
The old project (Gradle 6.7, AGP 4.1.0, `apply from: flutter.gradle`) no
longer builds with current Flutter.

Steps, run from the tabs_overlay directory:
1. rm -rf android
2. flutter create --platforms=android --org com.example \
        --project-name tabs_overlay .
3. git restore pubspec.lock .metadata  # unrelated from flutter create
4. rm test/widget_test.dart            # template sample test

   # Restore the app's native code and theme
5. git restore android/app/src/main/kotlin \
               android/app/src/main/res/layout \
               android/app/src/main/res/values

   # Drop the template's night theme (see below)
6. rm -r  android/app/src/main/res/values-night

Why remove values-night: The template's values-night/styles.xml
redefines LaunchTheme and NormalTheme on Theme.Black.NoTitleBar, which
isn't an AppCompat theme.  MainActivity is an AppCompatActivity, so in
dark mode the app would crash ("You need to use a Theme.AppCompat theme
(or descendant) with this activity"). The app's own values/styles.xml
already handles dark mode through Theme.MaterialComponents.DayNight.

No hand edits.

Doesn't build on its own. The template has no AndroidX dependencies.
The next commit will add those.
Hand edits to make the native side build:

- android/app/build.gradle.kts: add in dependencies old project
  declared.
  - material (keep at 1.4.0 rather than risk changing native tab
    appearance)
  - lifecycle moves explicitly to 2.7.0 to match flutter embedding
  - explicit kotlin-stdlib-jdk7 isn't needed. It's included by the
    Kotlin Gradle plugin.
- PageViewModel.kt: Transformations.map has moved from a static call to
  an extension function on LiveData.

After this commit the app builds/runs.
With targetSdk 36 (Flutter 3.47's default), Android 15+ draws the app
edge to edge, under the status bar. Flutter's AppBar insets itself for
the status bar, but the native AppBarLayout didn't, so it sat a status
bar's height higher. The opaque native page covered Flutter's tab bar,
and touches on the native tabs missed Flutter's tabs underneath.
Generated with `flutter pub add material_ui` (Flutter 3.47.7), which
picked ^1.7.0. No hand edits.

The lock also gains material_ui's dependencies it didn't have already
(cupertino_ui, flutter_localizations, intl), and its Flutter floor rises
to >=3.47.0 because material_ui requires Flutter 3.47.

Nothing imports material_ui yet. That happens in a subsequent commit.
Generated with `dart fix --apply --code=migrate_design_widgets`
(Dart 3.13.5). No hand edits.
@pjkammer pjkammer changed the title [tabs_overlay] Migrate to material_ui [tabs_overlay] Migrate to material_ui Oct 20, 2026
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

Successfully merging this pull request may close these issues.

1 participant