diff --git a/src/content/app-architecture/case-study/index.md b/src/content/app-architecture/case-study/index.md
index 4b27f04b57..20b8e47ba9 100644
--- a/src/content/app-architecture/case-study/index.md
+++ b/src/content/app-architecture/case-study/index.md
@@ -20,24 +20,11 @@ includes brand-specific styling, and contains high test coverage.
In these ways and more, it simulates a real-world,
feature-rich Flutter application.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {% render docs/app-figure.md, image:"app-architecture/case-study/splash_screen.png", alt:"A screenshot of the splash screen of the compass app.", img-style:"max-height: 400px;" %}
+ {% render docs/app-figure.md, image:"app-architecture/case-study/home_screen.png", alt:"A screenshot of the home screen of the compass app.", img-style:"max-height: 400px;" %}
+ {% render docs/app-figure.md, image:"app-architecture/case-study/search_form_screen.png", alt:"A screenshot of the search form screen of the compass app.", img-style:"max-height: 400px;" %}
+ {% render docs/app-figure.md, image:"app-architecture/case-study/booking_screen.png", alt:"A screenshot of the booking screen of the compass app.", img-style:"max-height: 400px;" %}
The Compass app's architecture most resembles the [MVVM design pattern][]
diff --git a/src/content/app-architecture/case-study/ui-layer.md b/src/content/app-architecture/case-study/ui-layer.md
index 900fb97663..ffc1712ea8 100644
--- a/src/content/app-architecture/case-study/ui-layer.md
+++ b/src/content/app-architecture/case-study/ui-layer.md
@@ -180,7 +180,7 @@ new state needs to be emitted, [`notifyListeners`][] is called.

-
+
This figure shows from a high-level how new data in the repository
propagates up to the UI layer and triggers a re-build of your Flutter widgets.
@@ -404,9 +404,11 @@ a [`Dismissible`][] widget.
Recall this code from the previous snippet:
-
-
-
+{% render docs/code-and-image.md,
+image:"app-architecture/case-study/dismissible.gif",
+img-style:"max-height: 480px; border-radius: 12px; border: black 2px solid;",
+alt: "A clip that demonstrates the 'dismissible' functionality of the Compass app."
+code:"
```dart title=home_screen.dart highlightLines=9-10
SliverList.builder(
itemCount: widget.viewModel.bookings.length,
@@ -421,13 +423,7 @@ SliverList.builder(
),
),
```
-
-
-
-
-
-
-
+" %}
On the `HomeScreen`, a user's saved trip is represented by
the `_Booking` widget. When a `_Booking` is dismissed,
diff --git a/src/content/app-architecture/index.md b/src/content/app-architecture/index.md
index 8fe5f58371..8c1df30728 100644
--- a/src/content/app-architecture/index.md
+++ b/src/content/app-architecture/index.md
@@ -7,17 +7,15 @@ toc: false
next:
title: Architecture concepts
path: /app-architecture/concepts
-
---
-
-
+
+
Architecture is an important part of building a
maintainable, resilient, and scalable Flutter app.
In this guide, you'll learn app architecture principles and
best practices for building Flutter apps.
-
'Architecture' is a word that's hard to define.
It's a broad term and can refer to any number
@@ -26,10 +24,8 @@ of topics depending on the context. In this guide,
your Flutter app in order to scale as your project requirements and team grow.
-
-
-
-
+
+
diff --git a/src/content/assets/js/main.js b/src/content/assets/js/main.js
index 7c9ffc4d22..dcd7267872 100644
--- a/src/content/assets/js/main.js
+++ b/src/content/assets/js/main.js
@@ -4,14 +4,14 @@ document.addEventListener("DOMContentLoaded", function(_) {
scrollSidenavIntoView();
initCookieNotice();
- setupMenuToggle();
+ setupSidenavInteractivity();
setUpCodeBlockButtons();
setupSearch();
setupTabs();
});
-function setupMenuToggle() {
+function setupSidenavInteractivity() {
document.getElementById('menu-toggle')?.addEventListener('click', function (e) {
e.stopPropagation();
document.body.classList.toggle('open_menu');
@@ -25,6 +25,15 @@ function setupMenuToggle() {
}
}
});
+
+ // Set up collapse and expand for sidenav buttons.
+ const toggles = document.querySelectorAll('.nav-link.collapsible');
+ toggles.forEach(function (toggle) {
+ toggle.addEventListener('click', (e) => {
+ toggle.classList.toggle('collapsed');
+ e.preventDefault();
+ });
+ });
}
/**
@@ -96,11 +105,6 @@ function adjustToc() {
});
}
- // This will not be migrated for now until we migrate
- // the entire site to Bootstrap 5.
- // see https://github.com/flutter/website/pull/9167#discussion_r1286457246
- $('body').scrollspy({ offset: 100, target: tocId });
-
function _scrollToTop() {
const distanceBetweenTop = document.documentElement.scrollTop || document.body.scrollTop;
if (distanceBetweenTop > 0) {
diff --git a/src/content/assets/js/page/install-current.js b/src/content/assets/js/page/install-current.js
index 0e45fee876..fa5d853ad8 100644
--- a/src/content/assets/js/page/install-current.js
+++ b/src/content/assets/js/page/install-current.js
@@ -11,9 +11,9 @@ document.addEventListener("DOMContentLoaded", function(_) {
osButton.classList.add('card-highlight');
- const header = osButton.querySelector('.card-title');
+ const header = osButton.querySelector('.card-header');
if (!header) return;
- const currentSubtitle = document.createElement('div');
+ const currentSubtitle = document.createElement('span');
currentSubtitle.textContent = 'Current device';
currentSubtitle.classList.add('card-subtitle');
header.appendChild(currentSubtitle);
diff --git a/src/content/data-and-backend/serialization/json.md b/src/content/data-and-backend/serialization/json.md
index c10f15b5bc..5b0afca77c 100644
--- a/src/content/data-and-backend/serialization/json.md
+++ b/src/content/data-and-backend/serialization/json.md
@@ -354,8 +354,7 @@ final String verificationCode;
When creating `json_serializable` classes the first time,
you'll get errors similar to what is shown in the image below.
-{:.mw-100}
+
These errors are entirely normal and are simply because the generated code for
the model class does not exist yet. To resolve this, run the code
diff --git a/src/content/get-started/codelab.md b/src/content/get-started/codelab.md
index 36f80ff5dd..8294590d58 100644
--- a/src/content/get-started/codelab.md
+++ b/src/content/get-started/codelab.md
@@ -25,7 +25,7 @@ that works on mobile, desktop, and web.
Unicode character.
The non-breaking space after it makes the button look nicer.
{% endcomment -%}
-
▶ Start codelab
diff --git a/src/content/get-started/fundamentals/index.md b/src/content/get-started/fundamentals/index.md
index 0cc0621465..ec3c68dd7e 100644
--- a/src/content/get-started/fundamentals/index.md
+++ b/src/content/get-started/fundamentals/index.md
@@ -9,8 +9,8 @@ toc: false
-
{% endfor %}
diff --git a/src/content/index.md b/src/content/index.md
index cbf4ab0f34..6f05d21cbc 100644
--- a/src/content/index.md
+++ b/src/content/index.md
@@ -6,13 +6,15 @@ description: Get started with Flutter. Widgets, examples, updates, and API docs
+ {% ytEmbed 'QlwiL_yLh6E', 'What is state?', true, true %}
+
[first-app]: {{site.yt.watch}}?v=xWV71C2kp38
@@ -103,16 +105,16 @@ using helper methods][standalone-widgets] or
[what is "BuildContext" and how is it used][buildcontext]?
[standalone-widgets]: {{site.yt.watch}}?v=IOyq-eTRhvo
@@ -123,6 +125,6 @@ see our [videos][] page.
We release new videos almost every week on the Flutter YouTube channel:
-Explore more Flutter videos
+Explore more Flutter videos
[videos]: /resources/videos
diff --git a/src/content/platform-integration/android/install-android/index.md b/src/content/platform-integration/android/install-android/index.md
index f221fabad7..d1b3fc57bd 100644
--- a/src/content/platform-integration/android/install-android/index.md
+++ b/src/content/platform-integration/android/install-android/index.md
@@ -23,25 +23,24 @@ or the platform you already have set up.
{% assign bug = 'card-chromeos' %}
{% endif %}
-
-
diff --git a/src/content/platform-integration/android/splash-screen.md b/src/content/platform-integration/android/splash-screen.md
index fddcf70ad5..b482df900d 100644
--- a/src/content/platform-integration/android/splash-screen.md
+++ b/src/content/platform-integration/android/splash-screen.md
@@ -4,8 +4,7 @@ short-title: Splash screen
description: Learn how to add a splash screen to your Android app.
---
-
+
Splash screens (also known as launch screens) provide
a simple initial experience while your Android app loads.
diff --git a/src/content/platform-integration/ios/install-ios/index.md b/src/content/platform-integration/ios/install-ios/index.md
index 996f2d2bff..b836bbaf5d 100644
--- a/src/content/platform-integration/ios/install-ios/index.md
+++ b/src/content/platform-integration/ios/install-ios/index.md
@@ -12,26 +12,22 @@ or the platform you already have set up.
{% for target in target-list %}
{% assign targetLink = '/platform-integration/ios/install-ios/install-ios-from-' | append: target | downcase %}
-
-
{% endfor %}
diff --git a/src/content/platform-integration/linux/install-linux/index.md b/src/content/platform-integration/linux/install-linux/index.md
index a63e865349..69225b33e2 100644
--- a/src/content/platform-integration/linux/install-linux/index.md
+++ b/src/content/platform-integration/linux/install-linux/index.md
@@ -12,22 +12,18 @@ or the platform you already have set up.
{% for target in target-list %}
{% assign targetLink = '/platform-integration/linux/install-linux/install-linux-from-' | append: target | downcase %}
-
-
{% endfor %}
diff --git a/src/content/platform-integration/macos/install-macos/index.md b/src/content/platform-integration/macos/install-macos/index.md
index b31611fbe7..198e78b639 100644
--- a/src/content/platform-integration/macos/install-macos/index.md
+++ b/src/content/platform-integration/macos/install-macos/index.md
@@ -12,26 +12,22 @@ or the platform you already have set up.
{% for target in target-list %}
{% assign targetLink = '/platform-integration/macos/install-macos/install-macos-from-' | append: target | downcase %}
-
-
{% endfor %}
diff --git a/src/content/platform-integration/windows/install-windows/index.md b/src/content/platform-integration/windows/install-windows/index.md
index 0e4c2c9e64..60f04da410 100644
--- a/src/content/platform-integration/windows/install-windows/index.md
+++ b/src/content/platform-integration/windows/install-windows/index.md
@@ -12,24 +12,20 @@ or the platform you already have set up.
{% for target in target-list %}
{% assign targetLink = '/platform-integration/windows/install-windows/install-windows-from-' | append: target | downcase %}
-
-
diff --git a/src/content/release/breaking-changes/androidx-migration.md b/src/content/release/breaking-changes/androidx-migration.md
index f56ad084c5..b81e57147f 100644
--- a/src/content/release/breaking-changes/androidx-migration.md
+++ b/src/content/release/breaking-changes/androidx-migration.md
@@ -35,23 +35,13 @@ you can download the latest version from the
but if it doesn't, select **Sync Project with Gradle Files**
from the **File** menu).
5. Select **Migrate to AndroidX** from the Refactor menu.
-6. If you are asked to backup the project before proceeding,
+6. If you're asked to back up the project before proceeding,
check **Backup project as Zip file**, then click **Migrate**.
Lastly, save the zip file in your location of preference.
-
+
7. The refactoring preview shows the list of changes.
Finally, click **Do Refactor**:
-
+
8. That is it! You successfully migrated your project to AndroidX.
Finally, if you migrated a plugin,
diff --git a/src/content/release/breaking-changes/flutter-driver-migration.md b/src/content/release/breaking-changes/flutter-driver-migration.md
index de37e6720f..ff35595422 100644
--- a/src/content/release/breaking-changes/flutter-driver-migration.md
+++ b/src/content/release/breaking-changes/flutter-driver-migration.md
@@ -30,7 +30,7 @@ functionality:
* The list of plants is loaded from a local JSON file located in the
`/assets` folder.
-
+
You can find the full code example in the [Example Project][] folder.
diff --git a/src/content/testing/integration-tests/index.md b/src/content/testing/integration-tests/index.md
index 4e9f4ed230..7dd2600abc 100644
--- a/src/content/testing/integration-tests/index.md
+++ b/src/content/testing/integration-tests/index.md
@@ -502,7 +502,7 @@ section of the README.
1. Navigate to **Quality > Test Lab**.
-
+
#### Upload an Android APK
@@ -536,7 +536,7 @@ To start a Robo test and run other tests, drag the "debug" APK from
`/build/app/outputs/apk/debug`
into the **Android Robo Test** target on the web page.
-
+
1. Click **Run a test**.
@@ -550,11 +550,11 @@ into the **Android Robo Test** target on the web page.
`/build/app/outputs/apk/androidTest/debug/.apk`
-
+
If a failure occurs, click the red icon to view the output:
-
+
#### Upload an Android APK from the command line
diff --git a/src/content/tools/vs-code.md b/src/content/tools/vs-code.md
index a45519c37c..03e2d11f4a 100644
--- a/src/content/tools/vs-code.md
+++ b/src/content/tools/vs-code.md
@@ -89,7 +89,7 @@ The code analysis can:
- You can also press Ctrl / Cmd +
Shift + M.
- The Problems pane displays any analysis issues:
- {:.mw-100 .pt-1}
+ 
## Running and debugging
@@ -115,7 +115,7 @@ When a Flutter project is open in VS Code,
you should see a set of Flutter specific entries in the status bar,
including a Flutter SDK version and a
device name (or the message **No Devices**):
-![VS Code status bar][]{:.mw-100 .pt-1}
+![VS Code status bar][]
:::note
- If you do not see a Flutter version number or device info,
@@ -155,7 +155,7 @@ You can also press Ctrl + F5.
1. Click **Run** > **Start Debugging**.
You can also press F5.
The status bar turns orange to show you are in a debug session.
- {:.mw-100 .pt-1}
+ 
- The left **Debug Sidebar** shows stack frames and variables.
- The bottom **Debug Console** pane shows detailed logging output.
diff --git a/src/content/ui/accessibility-and-internationalization/accessibility.md b/src/content/ui/accessibility-and-internationalization/accessibility.md
index 39e1b9eb66..38d842936f 100644
--- a/src/content/ui/accessibility-and-internationalization/accessibility.md
+++ b/src/content/ui/accessibility-and-internationalization/accessibility.md
@@ -78,13 +78,9 @@ The following two screenshots show the standard Flutter app
template rendered with the default iOS font setting,
and with the largest font setting selected in iOS accessibility settings.
-
## Screen readers
diff --git a/src/content/ui/adaptive-responsive/platform-adaptations.md b/src/content/ui/adaptive-responsive/platform-adaptations.md
index 4c9485321b..be9c9b6579 100644
--- a/src/content/ui/adaptive-responsive/platform-adaptations.md
+++ b/src/content/ui/adaptive-responsive/platform-adaptations.md
@@ -62,33 +62,10 @@ On **iOS**:
is true. This represents iOS's Present/Modal style
transition and is typically used on fullscreen modal pages.
-
-
-
-
-
-
- Android page transition
-
-
-
-
-
-
-
- iOS push transition
-
-
-
-
-
-
-
- iOS present transition
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/navigation-android.gif", img-style:"border-radius: 12px;", caption:"Android page transition", alt:"An animation of the bottom-up page transition on Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/navigation-ios.gif", img-style:"border-radius: 22px;", caption:"iOS push transition", alt:"An animation of the end-start style push page transition on iOS" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/navigation-ios-modal.gif", img-style:"border-radius: 22px;", caption:"iOS present transition", alt:"An animation of the bottom-up style present page transition on iOS" %}
[`Navigator.push()`]: {{site.api}}/flutter/widgets/Navigator/push.html
@@ -108,25 +85,9 @@ automatically animate each subcomponent to its corresponding
subcomponent on the next or previous page's
`CupertinoNavigationBar` or `CupertinoSliverNavigationBar`.
-
-
-
-
-
-
- Android
-
-
-
-
-
-
-
- iOS Nav Bar
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/android-zoom-animation.png", img-style:"border-radius: 12px;", caption:"Android", alt:"An animation of the page transition on Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/navigation-ios-nav-bar.gif", img-style:"border-radius: 22px;", caption:"iOS Nav Bar", alt:"An animation of the nav bar transitions during a page transition on iOS" %}
[`ZoomPageTransitionsBuilder`]: {{site.api}}/flutter/material/ZoomPageTransitionsBuilder-class.html
@@ -142,25 +103,9 @@ and pops the top route of the [`WidgetsApp`][]'s Navigator.
On **iOS**,
an edge swipe gesture can be used to pop the top route.
-
-
-
-
-
-
- Android back button
-
-
-
-
-
-
-
- iOS back swipe gesture
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/navigation-android-back.gif", img-style:"border-radius: 12px;", caption:"Android back button", alt:"A page transition triggered by the Android back button" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/navigation-ios-back.gif", img-style:"border-radius: 22px;", caption:"iOS back swipe gesture", alt:"A page transition triggered by an iOS back swipe gesture" %}
[`WidgetsApp`]: {{site.api}}/flutter/widgets/WidgetsApp-class.html
@@ -180,33 +125,10 @@ dynamic friction but Android has more static friction.
Therefore iOS gains high speed more gradually but stops
less abruptly and is more slippery at slow speeds.
-
-
-
-
-
-
- Soft fling comparison
-
-
-
-
-
-
-
- Medium fling comparison
-
-
-
-
-
-
-
- Strong fling comparison
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-soft.gif", caption:"Soft fling comparison", alt:"A soft fling where the iOS scrollable slid longer at lower speed than Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-medium.gif", caption:"Medium fling comparison", alt:"A medium force fling where the Android scrollable reaches speed faster and stopped more abruptly after reaching a longer distance" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-strong.gif", caption:"Strong fling comparison", alt:"A strong fling where the Android scrollable reaches speed faster and covered significantly more distance" %}
### Overscroll behavior
@@ -219,25 +141,9 @@ of the current Material theme).
On **iOS**, scrolling past the edge of a scrollable
[overscrolls][] with increasing resistance and snaps back.
-
-
-
-
-
-
- Dynamic overscroll comparison
-
-
-
-
-
-
-
- Static overscroll comparison
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-overscroll.gif", caption:"Dynamic overscroll comparison", alt:"Android and iOS scrollables being flung past their edge and exhibiting platform specific overscroll behavior" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-static-overscroll.gif", caption:"Static overscroll comparison", alt:"Android and iOS scrollables being overscrolled from a resting position and exhibiting platform specific overscroll behavior" %}
[overscroll glow indicator]: {{site.api}}/flutter/widgets/GlowingOverscrollIndicator-class.html
@@ -250,17 +156,8 @@ repeated flings in the same direction stacks momentum
and builds more speed with each successive fling.
There is no equivalent behavior on Android.
-
-
-
-
-
-
- iOS scroll momentum
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-momentum-ios.gif", caption:"iOS scroll momentum", alt:"Repeated scroll flings building momentum on iOS" %}
### Return to top
@@ -270,17 +167,8 @@ tapping the OS status bar scrolls the primary
scroll controller to the top position.
There is no equivalent behavior on Android.
-
-
-
-
-
-
- iOS status bar tap to top
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/scroll-tap-to-top-ios.gif", img-style:"border-radius: 22px;", caption:"iOS status bar tap to top", alt:"Tapping the status bar scrolls the primary scrollable back to the top" %}
## Typography
@@ -305,25 +193,9 @@ widgets to match the default text styling on iOS.
You can see widget-specific examples in the
[UI Component section](#ui-components).
-
-
-
-
-
-
- Roboto on Android
-
-
-
-
-
-
-
- San Francisco on iOS
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/typography-android.png", img-style:"border-radius: 12px;", caption:"Roboto on Android", alt:"Roboto font typography scale on Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/typography-ios.png", img-style:"border-radius: 22px;", caption:"San Francisco on iOS", alt:"San Francisco typography scale on iOS" %}
[default theme]: {{site.repo.flutter}}/blob/main/packages/flutter/lib/src/cupertino/text_theme.dart
@@ -338,25 +210,9 @@ are horizontal on iOS and vertical on Android.
The back button is a simple chevron on iOS and
has a stem/shaft on Android.
-
The material library also provides a set of
@@ -398,25 +254,9 @@ a force-press-drag gesture could be made on the soft
keyboard to move the cursor in 2D via a floating cursor.
This works on both Material and Cupertino text fields.
-
-
-
-
-
-
- Android space key cursor move
-
-
-
-
-
-
-
- iOS 3D Touch drag cursor move
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-keyboard-move-android.gif", caption:"Android space key cursor move", alt:"Moving the cursor via the space key on Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/text-keyboard-move-ios.gif", caption:"iOS 3D Touch drag cursor move", alt:"Moving the cursor via 3D Touch drag on the keyboard on iOS" %}
### Text selection toolbar
@@ -429,25 +269,9 @@ With **Material on iOS** or when using **Cupertino**,
the iOS style selection toolbar is shown when a text
selection is made in a text field.
-
-
-
-
-
-
- Android text selection toolbar
-
-
-
-
-
-
-
- iOS text selection toolbar
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-toolbar-android.png", caption:"Android text selection toolbar", alt:"Android appropriate text toolbar" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/text-toolbar-ios.png", caption:"iOS text selection toolbar", alt:"iOS appropriate text toolbar" %}
### Single tap gesture
@@ -465,25 +289,9 @@ nearest edge of the word tapped.
Collapsed text selections don't have draggable handles on iOS.
-
-
-
-
-
-
- Android tap
-
-
-
-
-
-
-
- iOS tap
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-single-tap-android.gif", caption:"Android tap", alt:"Moving the cursor to the tapped position on Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/text-single-tap-ios.gif", caption:"iOS tap", alt:"Moving the cursor to the nearest edge of the tapped word on iOS" %}
### Long-press gesture
@@ -496,25 +304,9 @@ With **Material on iOS** or when using **Cupertino**,
a long press places the cursor at the location of the
long press. The selection toolbar is shown upon release.
-
-
-
-
-
-
- Android long press
-
-
-
-
-
-
-
- iOS long press
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-long-press-android.gif", caption:"Android long press", alt:"Selecting a word with long press on Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/text-long-press-ios.gif", caption:"iOS long press", alt:"Selecting a position with long press on iOS" %}
### Long-press drag gesture
@@ -525,25 +317,9 @@ dragging while holding the long press expands the words selected.
With **Material on iOS** or when using **Cupertino**,
dragging while holding the long press moves the cursor.
-
-
-
-
-
-
- Android long press drag
-
-
-
-
-
-
-
- iOS long press drag
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-long-press-drag-android.gif", caption:"Android long-press drag", alt:"Expanding word selection with a long-press drag on Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/text-long-press-drag-ios.gif", caption:"iOS long-press drag", alt:"Moving the cursor with a long-press drag on iOS" %}
### Double tap gesture
@@ -552,25 +328,9 @@ On both Android and iOS,
a double tap selects the word receiving the
double tap and shows the selection toolbar.
-
-
-
-
-
-
- Android double tap
-
-
-
-
-
-
-
- iOS double tap
-
-
-
-
+
+ {% render docs/app-figure.md, image:"platform-adaptations/text-double-tap-android.gif", caption:"Android double tap", alt:"Selecting a word via double tap on Android" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/text-double-tap-ios.gif", caption:"iOS double tap", alt:"Selecting a word via double tap on iOS" %}
## UI components
@@ -597,13 +357,13 @@ Therefore, we recommend that you follow platform conventions.
| Material widget | Cupertino widget | Adaptive constructor |
|---|---|---|
-| `Switch`| `CupertinoSwitch`|[`Switch.adaptive()`][]|
-| `Slider`| `CupertinoSlider`|[`Slider.adaptive()`][]|
-| `CircularProgressIndicator`| `CupertinoActivityIndicator`|[`CircularProgressIndicator.adaptive()`][]|
-| `RefreshProgressIndicator`| `CupertinoActivityIndicator`|[`RefreshIndicator.adaptive()`][]|
-| `Checkbox`| `CupertinoCheckbox`|[`Checkbox.adaptive()`][]|
-| `Radio`| `CupertinoRadio`|[`Radio.adaptive()`][]|
-| `AlertDialog`| `CupertinoAlertDialog`|[`AlertDialog.adaptive()`][]|
+| `Switch`| `CupertinoSwitch`|[`Switch.adaptive()`][]|
+| `Slider`| `CupertinoSlider`|[`Slider.adaptive()`][]|
+| `CircularProgressIndicator`| `CupertinoActivityIndicator`|[`CircularProgressIndicator.adaptive()`][]|
+| `RefreshProgressIndicator`| `CupertinoActivityIndicator`|[`RefreshIndicator.adaptive()`][]|
+| `Checkbox`| `CupertinoCheckbox`|[`Checkbox.adaptive()`][]|
+| `Radio`| `CupertinoRadio`|[`Radio.adaptive()`][]|
+| `AlertDialog`| `CupertinoAlertDialog`|[`AlertDialog.adaptive()`][]|
[`AlertDialog.adaptive()`]: {{site.api}}/flutter/material/AlertDialog/AlertDialog.adaptive.html
[`Checkbox.adaptive()`]: {{site.api}}/flutter/material/Checkbox/Checkbox.adaptive.html
@@ -618,29 +378,11 @@ Therefore, we recommend that you follow platform conventions.
Since Android 12, the default UI for top app
bars follows the design guidelines defined in [Material 3][mat-appbar].
On iOS, an equivalent component called "Navigation Bars"
-is defined in [Apple's Human Interface Guidelines][hig-appbar] (HIG).
-
-
-
-
-
-
-
- Top App Bar in Material 3
-
-
-
-
-
-
-
- Navigation Bar in Human Interface Guidelines
-
-
-
-
+is defined in [Apple's Human Interface Guidelines][hig-appbar] (HIG).
+
+
+ {% render docs/app-figure.md, image:"platform-adaptations/mat-appbar.png", caption:"Top App Bar in Material 3", alt:"Top App Bar in Material 3", height: "240px" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/hig-appbar.png", caption:"Navigation Bar in Human Interface Guidelines", alt:"Navigation Bar in Human Interface Guidelines", height: "240px" %}
Certain properties of app bars in Flutter apps should be adapted,
@@ -693,29 +435,11 @@ additional code samples and a further explanation in
Since Android 12, the default UI for bottom navigation
bars follow the design guidelines defined in [Material 3][mat-navbar].
On iOS, an equivalent component called "Tab Bars"
-is defined in [Apple's Human Interface Guidelines][hig-tabbar] (HIG).
-
-
-
-
-
-
-
- Bottom Navigation Bar in Material 3
-
-
-
-
-
-
-
- Tab Bar in Human Interface Guidelines
-
-
-
-
+is defined in [Apple's Human Interface Guidelines][hig-tabbar] (HIG).
+
+
+ {% render docs/app-figure.md, image:"platform-adaptations/mat-navbar.png", caption:"Bottom Navigation Bar in Material 3", alt:"Bottom Navigation Bar in Material 3", height: "160px" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/hig-tabbar.png", caption:"Tab Bar in Human Interface Guidelines", alt:"Tab Bar in Human Interface Guidelines", height: "160px" %}
Since tab bars are persistent across your app, they should match your
@@ -777,29 +501,11 @@ Scaffold(
Since Android 12, text fields follow the
[Material 3][m3-text-field] (M3) design guidelines.
On iOS, Apple's [Human Interface Guidelines][hig-text-field] (HIG) define
-an equivalent component.
-
-
-
-
-
-
-
- Text Field in Material 3
-
-
-
-
-
-
-
- Text Field in HIG
-
-
-
-
+an equivalent component.
+
+
+ {% render docs/app-figure.md, image:"platform-adaptations/m3-text-field.png", caption:"Text Field in Material 3", alt:"Text Field in Material 3", width:"320px", height:"100px" %}
+ {% render docs/app-figure.md, image:"platform-adaptations/hig-text-field.png", caption:"Text Field in HIG", alt:"Text Field in Human Interface Guidelines", width:"320px", height:"100px" %}
Since text fields require user input,
diff --git a/src/content/ui/animations/hero-animations.md b/src/content/ui/animations/hero-animations.md
index 3b146b5d7f..d181ad8a5c 100644
--- a/src/content/ui/animations/hero-animations.md
+++ b/src/content/ui/animations/hero-animations.md
@@ -286,11 +286,7 @@ The custom PhotoHero class maintains the hero,
and its size, image, and behavior when tapped.
The PhotoHero builds the following widget tree:
-
-
- 
-
-
+{% render docs/app-figure.md, image:"ui/animations/photohero-class.png", alt:"PhotoHero class widget tree %}
Here's the code:
@@ -552,11 +548,7 @@ with a rectangular clip (that remains a constant size throughout).
To do this, it builds the following widget tree:
-
+{% render docs/app-figure.md, image:"ui/animations/radial-expansion-class.png", alt:"RadialExpansion widget tree" %}
Here's the code:
diff --git a/src/content/ui/animations/index.md b/src/content/ui/animations/index.md
index 36708c14ac..4cbe1f0ab9 100644
--- a/src/content/ui/animations/index.md
+++ b/src/content/ui/animations/index.md
@@ -32,8 +32,7 @@ As shown in the video, the following
decision tree helps you decide what approach
to use when implementing a Flutter animation:
-
+
## Animation deep dive
diff --git a/src/content/ui/animations/tutorial.md b/src/content/ui/animations/tutorial.md
index 2e212deb08..3518a8dae3 100644
--- a/src/content/ui/animations/tutorial.md
+++ b/src/content/ui/animations/tutorial.md
@@ -391,8 +391,7 @@ dirty as necessary, so you don't need to call `addListener()`.
The widget tree for the [animate4][]
example looks like this:
-
+{% render docs/app-figure.md, image:"ui/AnimatedBuilder-WidgetTree.png", alt:"AnimatedBuilder widget tree" %}
Starting from the bottom of the widget tree, the code for rendering
the logo is straightforward:
diff --git a/src/content/ui/design/text/typography.md b/src/content/ui/design/text/typography.md
index 272ab06c76..a0c11079b2 100644
--- a/src/content/ui/design/text/typography.md
+++ b/src/content/ui/design/text/typography.md
@@ -45,8 +45,7 @@ There are also three size variations for each:
Each of these fifteen combinations of a category and text size are represented
by a single [`TextStyle`][].
-
+
All the platform specific typographical scales that Flutter exposes are
contained in the [`Typography`][] class. Usually, you will not need to
@@ -73,8 +72,7 @@ A growing number of fonts on Google Fonts offer some variable font capabilities.
You can see the range of options by using the Type Tester and see how you
might vary a single font.
-
+
In real time, move the slider on any of the axes to
see how it affects the font. When programming a variable font,
diff --git a/src/content/ui/interactivity/index.md b/src/content/ui/interactivity/index.md
index f02aec2191..f7ccb0d72e 100644
--- a/src/content/ui/interactivity/index.md
+++ b/src/content/ui/interactivity/index.md
@@ -33,7 +33,7 @@ replacing the solid star with an outline and
decreasing the count. Tapping again favorites the lake,
drawing a solid star and increasing the count.
-
+{% render docs/app-figure.md, image:"ui/favorited-not-favorited.png", alt:"The custom widget you'll create" %}
To accomplish this, you'll create a single custom widget
that includes both the star and the count,
@@ -349,17 +349,17 @@ creates a container that, when tapped, toggles between a
green or grey box. The `_active` boolean determines the
color: green for active or grey for inactive.
-
-
-
-
+
+
+
+
These examples use [`GestureDetector`][] to capture activity
on the `Container`.
-
+
### The widget manages its own state
diff --git a/src/content/ui/layout/constraints.md b/src/content/ui/layout/constraints.md
index c8c00fc51d..c92b7ab0f9 100644
--- a/src/content/ui/layout/constraints.md
+++ b/src/content/ui/layout/constraints.md
@@ -9,8 +9,7 @@ js:
-
+
:::note
If you are experiencing specific layout errors,
@@ -61,7 +60,7 @@ For example, if a composed widget contains a column
with some padding, and wants to lay out its two children
as follows:
-
+
The negotiation goes something like this:
@@ -1300,7 +1299,7 @@ The examples are explained in the following sections.
### Example 1
-
+
```dart
@@ -1314,7 +1313,7 @@ So the `Container` fills the screen and paints it red.
### Example 2
-
+
```dart
@@ -1329,7 +1328,7 @@ So the `Container` fills the screen.
### Example 3
-
+
```dart
@@ -1347,7 +1346,7 @@ can indeed be 100 × 100.
### Example 4
-
+
```dart
@@ -1367,7 +1366,7 @@ available space.
### Example 5
-
+
```dart
@@ -1387,7 +1386,7 @@ it just fills the screen.
### Example 6
-
+
```dart
@@ -1414,7 +1413,7 @@ how it behaves, depending on the circumstances.
### Example 7
-
+
```dart
@@ -1445,7 +1444,7 @@ entirely covers the red `Container`.
### Example 8
-
+
```dart
@@ -1467,7 +1466,7 @@ in the previous example.
### Example 9
-
+
```dart
@@ -1494,7 +1493,7 @@ to also assume the size of the screen, thus ignoring its
### Example 10
-
+
```dart
@@ -1521,7 +1520,7 @@ so it ends up having 70 (the minimum).
### Example 11
-
+
```dart
@@ -1548,7 +1547,7 @@ so it ends up having 150 (the maximum).
### Example 12
-
+
```dart
@@ -1575,7 +1574,7 @@ since that's between 70 and 150.
### Example 13
-
+
```dart
@@ -1590,7 +1589,7 @@ lets its child `Container` be any size it wants.
### Example 14
-
+
```dart
@@ -1610,7 +1609,7 @@ the much dreaded "overflow warning".
### Example 15
-
+
```dart
@@ -1638,7 +1637,7 @@ with no warnings given.
### Example 16
-
+
```dart
@@ -1657,7 +1656,7 @@ the following message: `BoxConstraints forces an infinite width.`
### Example 17
-
+
```dart
@@ -1689,7 +1688,7 @@ and a `ConstrainedBox`.
### Example 18
-
+
```dart
@@ -1710,7 +1709,7 @@ the available width.
### Example 19
-
+
```dart
@@ -1732,7 +1731,7 @@ no scaling happens.
### Example 20
-
+
```dart
@@ -1754,7 +1753,7 @@ and resizes `Text` so that it fits the screen, too.
### Example 21
-
+
```dart
@@ -1770,7 +1769,7 @@ and breaks the line so that it fits the screen.
### Example 22
-
+
```dart
@@ -1790,7 +1789,7 @@ and you'll see an error in the console.
### Example 23
-
+
```dart
@@ -1813,7 +1812,7 @@ and any extra space remains empty.
### Example 24
-
+
```dart
@@ -1839,7 +1838,7 @@ the available width of the `Row`. In this case, just like an
### Example 25
-
+
```dart
@@ -1873,7 +1872,7 @@ the original child's width becomes irrelevant, and is ignored.
### Example 26
-
+
```dart
@@ -1911,7 +1910,7 @@ its children.
### Example 27
-
+
```dart
@@ -1955,7 +1954,7 @@ when you use `Expanded` or `Flexible`.
### Example 28
-
+
```dart
@@ -1985,7 +1984,7 @@ to its child. More on that later.
### Example 29
-
+
```dart
@@ -2177,7 +2176,7 @@ Here's an example:
`performLayout()`. This is the method that does
the layout for the `Column`.
-
+
---
diff --git a/src/content/ui/layout/index.md b/src/content/ui/layout/index.md
index aac8d72af6..8a23a0ec2e 100644
--- a/src/content/ui/layout/index.md
+++ b/src/content/ui/layout/index.md
@@ -9,8 +9,6 @@ description: Learn how Flutter's layout mechanism works and how to build a layou
-
-
:::secondary What's the point?
* Widgets are classes used to build UIs.
* Widgets are used for both layout and UI elements.
@@ -29,10 +27,12 @@ You create a layout by composing widgets to build more complex widgets.
For example, the first screenshot below shows 3 icons with a label
under each one:
-
-
-
-
+
+
+
+
+
+
@@ -49,7 +49,7 @@ For more information, see
Here's a diagram of the widget tree for this UI:
-
+
Most of this should look as you might expect, but you might be wondering
about the containers (shown in pink). [`Container`][] is a widget class
@@ -285,22 +285,19 @@ or background color. If you want these features in a non-Material app,
you have to build them yourself. This app changes the background
color to white and the text to dark grey to mimic a Material app.
-
-
+
+
- That's it! When you run the app, you should see _Hello World_.
+That's it! When you run the app, you should see _Hello World_.
- App source code:
+App source code:
- * [Material app]({{examples}}/layout/base)
- * [Non-Material app]({{examples}}/layout/non_material)
+* [Material app]({{examples}}/layout/base)
+* [Non-Material app]({{examples}}/layout/non_material)
-
## Lay out multiple widgets vertically and horizontally
@@ -333,13 +330,11 @@ columns inside of rows or columns.
This layout is organized as a `Row`. The row contains two children:
a column on the left, and an image on the right:
-
+
The left column's widget tree nests rows and columns.
-
+
You'll implement some of Pavlova's layout code in
[Nesting rows and columns](#nesting-rows-and-columns).
@@ -365,11 +360,13 @@ For a row, the main axis runs horizontally and the cross axis runs
vertically. For a column, the main axis runs vertically and the cross
axis runs horizontally.
-
-
-
+
+
+
+
+
+
+
The [`MainAxisAlignment`][] and [`CrossAxisAlignment`][]
@@ -391,24 +388,24 @@ is more than 300 pixels wide, so setting the main axis
alignment to `spaceEvenly` divides the free horizontal
space evenly between, before, and after each image.
-
@@ -420,8 +417,8 @@ of 3 images, each is 100 pixels high. The height of the render box
setting the main axis alignment to `spaceEvenly` divides the free vertical
space evenly between, above, and below each image.
-
-
+
+
```dart
@@ -435,12 +432,11 @@ space evenly between, above, and below each image.
);
```
- **App source:** [row_column]({{examples}}/layout/row_column)
-
@@ -450,15 +446,15 @@ When a layout is too large to fit a device, a yellow
and black striped pattern appears along the affected edge.
Here is an [example][sizing] of a row that is too wide:
-
+
Widgets can be sized to fit within a row or column by using the
[`Expanded`][] widget. To fix the previous example where the
row of images is too wide for its render box,
wrap each image with an `Expanded` widget.
-
-
+
+
```dart
@@ -479,9 +475,8 @@ wrap each image with an `Expanded` widget.
```
@@ -493,8 +488,8 @@ an integer that determines the flex factor for a widget.
The default flex factor is 1. The following code sets
the flex factor of the middle image to 2:
-
-
+
+
```dart
@@ -516,9 +511,8 @@ the flex factor of the middle image to 2:
```
@@ -533,8 +527,8 @@ as possible, but if you want to pack the children closely together,
set its `mainAxisSize` to `MainAxisSize.min`. The following example
uses this property to pack the star icons together.
-
-
+
+
```dart
@@ -551,9 +545,8 @@ uses this property to pack the star icons together.
```
@@ -566,8 +559,7 @@ inside of rows and columns as deeply as you need.
Let's look at the code for the outlined
section of the following layout:
-
+
The outlined section is implemented as two rows. The ratings row contains
five stars and the number of reviews. The icons row contains three
@@ -575,7 +567,7 @@ columns of icons and text.
The widget tree for the ratings row:
-
+
The `ratings` variable creates a row containing a smaller row
of 5-star icons, and text:
@@ -624,7 +616,7 @@ The icons row, below the ratings row, contains 3 columns;
each column contains an icon and two lines of text,
as you can see in its widget tree:
-
+
The `iconList` variable defines the icons row:
@@ -783,20 +775,19 @@ You can change the device's background by placing the
entire layout into a `Container` and changing its background
color or image.
-
-
-
Summary (Container)
+
+
+
+#### Summary (Container)
* Add padding, margins, borders
* Change background color or image
-* Contains a single child widget, but that child can be a Row,
- Column, or even the root of a widget tree
+* Contains a single child widget, but that child can be a `Row`,
+ `Column`, or even the root of a widget tree
-
-
+
+
@@ -806,8 +797,8 @@ This layout consists of a column with two rows, each containing
2 images. A [`Container`][] is used to change the background color
of the column to a lighter grey.
-
-
+
+
```dart
@@ -827,9 +818,8 @@ of the column to a lighter grey.
```
-
-
+
+
@@ -895,25 +885,24 @@ it's the entry in the "calorie" column for the "avocado" row), use
#### Examples (GridView)
-
-
-
+
+
+
Uses `GridView.extent` to create a grid with tiles a maximum
150 pixels wide.
**App source:** [grid_and_list]({{examples}}/layout/grid_and_list)
-
-
+
+
Uses `GridView.count` to create a grid that's 2 tiles
wide in portrait mode, and 3 tiles wide in landscape mode.
The titles are created by setting the `footer` property for
each [`GridTile`][].
- **Dart code:**
+ **Dart code:**
[`grid_list_demo.dart`]({{examples}}/layout/gallery/lib/grid_list_demo.dart)
+
Uses `ListView` to display a list of businesses using
`ListTile`s. A `Divider` separates the theaters from
@@ -963,9 +951,8 @@ its render box.
**App source:** [grid_and_list]({{examples}}/layout/grid_and_list)
-
-
+
+
Uses `ListView` to display the [`Colors`][] from
the [Material 2 Design palette][]
@@ -1031,9 +1018,9 @@ or partially overlap the base widget.
#### Examples (Stack)
-
-
-
+
+
+
Uses `Stack` to overlay a `Container`
(that displays its `Text` on a translucent
@@ -1043,8 +1030,8 @@ or partially overlap the base widget.
**App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
-
-
+
+
Uses `Stack` to overlay an icon on top of an image.
@@ -1116,9 +1103,9 @@ Specifying an unsupported value disables the drop shadow entirely.
#### Examples (Card)
-
-
-
+
+
+
A `Card` containing 3 ListTiles and sized by wrapping
it with a `SizedBox`. A `Divider` separates the first
@@ -1126,9 +1113,8 @@ Specifying an unsupported value disables the drop shadow entirely.
**App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
-
-
+
+
A `Card` containing an image and text.
@@ -1200,17 +1186,16 @@ and trailing icons. `ListTile` is most commonly used in
#### Examples (ListTile)
-
-
-
+
+
+
A `Card` containing 3 `ListTile`s.
**App source:** [card_and_stack]({{examples}}/layout/card_and_stack)
-
-
+
+
Uses `ListTile` with leading widgets.
diff --git a/src/content/ui/navigation/deep-linking.md b/src/content/ui/navigation/deep-linking.md
index 7116d138e2..637e10f9e3 100644
--- a/src/content/ui/navigation/deep-linking.md
+++ b/src/content/ui/navigation/deep-linking.md
@@ -39,18 +39,14 @@ If you are a visual learner, check out the following video:
To get started, see our cookbooks for Android and iOS:
diff --git a/src/content/ui/widgets/index.md b/src/content/ui/widgets/index.md
index e6dd214ff5..c0677ffc51 100644
--- a/src/content/ui/widgets/index.md
+++ b/src/content/ui/widgets/index.md
@@ -16,14 +16,16 @@ Flutter ships with two design systems as part of the SDK.
{% assign categories = catalog.index | sort: 'name' -%}
{% for section in categories %}
- {%- if section.name == "Cupertino" or section.name == "Material components" -%}
-