text:
[native_assets] Stop doing dry run in flutter run

We introduced dry-runs to build hooks due to flutter run running concurrently with the inner flutter assemble.
Now we have made the native_assets_builder wait on concurrent invocations, we should be able to do full builds in flutter run which will then be picked up by flutter assemble also invoking the native_assets_builder.
This will simplify the user experience, as there is no longer any reasoning about dry runs or not.
For more info:

https://github.com/dart-lang/native/issues/1485

We can't easily get rid of dry-run in flutter run.
Some information need to run hooks is only defined in the native builds (XCodeBuild, Grade, CMake), and only available to flutter assemble:

Android Minimum SDK version
iOS/MacOS code sign identity. We might be able to sign with the empty identity. But that would lead to two different binaries within flutter run (empty identity) and flutter assemble (the identity chosen in the xcodeproject)

Not available in flutter run, but we could work around it:

iOS SDK (emulator vs device). We could take the info from the devices instead of the SDK root environment variable.
Target architectures. We could take the info from the devices instead of the SDK root environment variable.

Some information is available in flutter run:

Build mode (release vs debug, the flag is explicit in flutter run)
iOS/MacOS minimum SDK version (hardcoded in Flutter tools). If Flutter ever decides to get this value from the XCodeBuild it would have the same issue as Android Minimum SDK.

We could start defining the minimum Android SDK version in Flutter apps in the pubspec. This has the issue that now we have information in two places, in the native build files of the Android app, and in the pubspec. And users can let these go out of sync. An alternative that doesn't work is to invoke the build with Flutter's lowest supported Android minimum SDK version. But that would make flutter run fail if a build hook and app can both do a newer version, but not the lowest version.
I think a somewhat deeper design question is where Flutter wants to have configuration such as which hardware architectures are supported and what the minimum OS SDK is. Currently, these are defined in the native builds. This means they cannot be surfaced on pub for example (https://github.com/dart-lang/pub/issues/4367). cc @andrewkolos @christopherfujino @stuartmorgan
I'd prefer having a way to specify such constraints that is not flutter specific, but that would work in Dart standalone packages as well. Of course that would lead to duplicate specification, both in the generated flutter native build system files for a Flutter app, and the pubspec. But maybe it would be possible to read them from the pubspec in the native build files?
FYI @mkustermann

We could start defining the minimum Android SDK version in Flutter apps in the pubspec. This has the issue that now we have information in two places, in the native build files of the Android app, and in the pubspec. And users can let these go out of sync.

I'm not clear on what the advantage would be that would offset these downsides. If we need this information, why not just read it out of the source-of-truth files?

I think a somewhat deeper design question is where Flutter wants to have configuration such as which hardware architectures are supported and what the minimum OS SDK is. Currently, these are defined in the native builds.

Why wouldn't they be? The only other use case I've ever heard for this information beyond the native builds themselves is to use as a constraint in pub resolution, and there has been significant resistance to adding those dimensions to the constraint matrix.

This means they cannot be surfaced on pub for example (dart-lang/pub-dev#8010).

Why couldn't pub.dev read the actual value for these from the source of truth, rather than a copy that has no enforcement and could, as you pointed out, easily become out of sync?

I'd prefer having a way to specify such constraints that is not flutter specific, but that would work in Dart standalone packages as well.

The prior art here would be the top-level platforms: tag, which is used when present, and when it isn't uses the plugin source of truth (flutter:plugin:platforms:).

The last few days I've been looking into the code bases of the native asset system in flutter and outside of flutter and I encounter complexity everywhere - and I really wonder whether this complexity is actually needed or justified.

We can't easily get rid of dry-run in flutter run.
Some information need to run hooks is only defined in the native builds (XCodeBuild, Grade, CMake), and only available to flutter assemble:

Android Minimum SDK version
...

The flutter assemble command will trigger the build of native code in all transitive packages. That command should know everything it needs to know about the target we compile for and can pass that information to all the build scripts of packages that have native code (i.e. flutter assemble will invoke hook/build.dart of packages and provides it with a build config that includes android SDK versions, etc).

Not available in flutter run, but we could work around it:

Target architectures. We could take the info from the devices instead of the SDK root environment variable.
...

I think the complexity arises because the responsibility of dealing with code assets isn't in one place but split between

flutter assemble: It does the actual build of native code
flutter run: It does a dry run invocation - to see what native assets will be there (once the build will be done) - it then makes a native_assets.yaml,  compiles that to kernel, includes that into the application kernel file.

How about we do this differently

flutter run will not do any dry run, it will simply invoke the native build system, which will then invoke flutter assemble.
flutter assemble will build the native code for all packages as it already does now and puts them into build/native_assets/**/*.so
=> We'll make it now also emit a small native_libs.txt file describing all the native assets it has built (it actually already has a build/native_assets/**/native_assets.yaml - but that is used for a different purpose and has Dart SDK specified format -- we don't need that here)
the native build (e.g. cmake, gradle) copies (as it already does currently) the build/native_assets/* into the actual bundle (e.g. build/linux/x64/debug/bundle/lib/*) - both all the native libraries but also the native_libs.txt
we make the flutter runtime use a custom library & symbol resolution via Dart_InitializeNativeAssetsResolver instead of using the standalone embedders resolution mechanism
=> The implementation here will then use native_libs.txt to load the corresponding libraries

This would allow us to remove all the complexity introduced into flutter tools that deals with native_assets.yaml, it's kernel compilation, kernel concatenation.
=> We make flutter decide how to bundle & load code assets (instead of trying to force us to do it the same way as standalone dart embedder does it).
If that works, then we can also get remove this dry-run complexity in the Dart hook build/link protocol.
@dcharkes Would that work?

Additional question:

Some information is only ... available to flutter assemble:
...
Not available in flutter run

flutter run (indirectly, via the native build system) calls flutter assemble. Therefore flutter assemble could just return this information to flutter run (e.g. by writing it out somewhere), can't it?
It may be just the way things got currently wired up with the native_asset.yaml complexity is that flutter run may? currently want this information before it calls (indirectly) flutter assemble. Though given my thoughts above, I think it should be sufficient to have that information after it (indirectly) calls flutter assemble.

we make the flutter runtime use a custom library & symbol resolution via Dart_InitializeNativeAssetsResolver instead of using the standalone embedders resolution mechanism

These functions assume the native_assets.yaml has already been used to do the native assets id to to path mapping and take a path as argument. We could change that, but that would prevent us from bundling the native assets mapping inside a kernel file, which would break Isolate.spawnUri in the standalone (and possible other) embedders.

I think the complexity arises because the responsibility of dealing with code assets isn't in one place but split between

Completely agreed. If we could limit it to one place, that would be great.
If we assume that we need the mapping inside the kernel file to support Isolate.spawnUri, maybe there's still a way to reuse what flutter assemble computed in flutter run. Since we already compile the native assets mapping to a separate kernel file (https://github.com/flutter/flutter/pull/147158), maybe we could put the output kernel file of KernelSnapshotNativeAssets in a location where flutter run can pick it up and concatenate it with its compiled kernel file.

It may be just the way things got currently wired up with the native_asset.yaml complexity is that flutter run may? currently want this information before it (indirectly) calls flutter assemble. Though given my thoughts above, I think it should be sufficient to have that information after it (indirectly) calls flutter assemble.

This is a correct assessment. The kernel compilation in flutter run (for the support of immediate hot reload and hot restart) happens concurrently with the native build invocation. If the kernel compilation in flutter run would be delayed until after the native build returns, we could indeed reuse the information from flutter assemble (either the BuildConfig info, or the kernel file containing the mapping).

We could change that, but that would prevent us from bundling the native assets mapping inside a kernel file, which would break Isolate.spawnUri in the standalone (and possible other) embedders.

This issue is about the flutter embedder, and flutter disallows Isolate.spawnUri (i.e. it's an API that doesn't work in flutter). So if there's not any other reasons flutter may require dry-run, I think getting rid of the dry-run usage in flutter makes sense - it will simplify things considerably.
We can then discuss to what extend the dry-run functionality is needed for our standalone embedder and if we can find another solution there as well.

We could change that, but that would prevent us from bundling the native assets mapping inside a kernel file, which would break Isolate.spawnUri in the standalone (and possible other) embedders.

This issue is about the flutter embedder, and flutter disallows Isolate.spawnUri (i.e. it's an API that doesn't work in flutter). So if there's not any other reasons flutter may require dry-run, I think getting rid of the dry-run usage in flutter makes sense - it will simplify things considerably.
We can then discuss to what extend the dry-run functionality is needed for our standalone embedder and if we can find another solution there as well - thereby being able to remove it entirely from the protocol

I think I did not explain this clearly or you misunderstood. We a native assets kernel mapping in the flutter run for hot reload and hot restart support, not for spawnUri support. We need the mapping inside the kernel file for supporting spawnUri. We don't need dry run in Dart standalone.
I am assuming we'd want one set of functions in Dart_InitializeNativeAssetsResolver. That set of functions needs to support spawnUri. So, that set of functions must be in some way linked to embedding the mapping inside the kernel file. (The current way it's linked is that the asset id is resolved to a path in the VM before calling the embedder function.) We could opt to add a new function to the Dart_InitializeNativeAssetsResolver that takes an asset ID and symbol. Then the flutter embedder would only provide that function and leave all the others null, and the Dart embedder would leave the new function null.

I think I did not explain this clearly or you misunderstood. We a native assets kernel mapping in the flutter run for hot reload and hot restart support, not for spawnUri support.

Why is there a need for this mapping to be shipped as part of a kernel file? This information has to be made available to the runtime (in AOT and in JIT / hot-reload) somehow but not necessarily as part of the kernel file.
While reading the flutter code, it seems it already has plenty of infrastructure for having other files as part of the app and synchronizing those to device as part of hot-reload (and bundling them for release builds). So instead of having a specialized solution with this kernel embedding, we could just take advantage of the existing mechanism flutter already uses. It may be as simple as dropping a code_assets.txt file in the build/flutter_assets folder - which flutter's existing infrastructure synchronizes to the device in hot-reload (and bundles in AOT mode) where the runtime can access it.
So my suggestion would be to re-use that - from reading through the code that would be a more natural way of doing it and probably simplify a bunch of things in the flutter tools.

I am assuming we'd want one set of functions in Dart_InitializeNativeAssetsResolver. That set of functions needs to support spawnUri. So, that set of functions must be in some way linked to embedding the mapping inside the kernel file.

Conceptually this interface should maybe different from what it is now: Dart_InitializeNativeAssetsResolver could take these functions:
LibraryHandle ObtainLibraryForAssetId(const char* asset_id);
void* LookupSymbolInAssetId(LibraryHandle handle, const char* symbol_name);
void CloseLibrary(LibraryHandle handle);

So the embedder is given an asset id and a symbol (this would be symmetric to how e.g. we'd ask an embedder to load a data asset - or other resources identified by an id).
That means the txt file flutter embedder embeds contains information for each asset_id whether it's in executable, process, shared library (with path), ...

Why is there a need for this mapping to be shipped as part of a kernel file?

Isolate.spawnUri takes one argument for the uri, not a second argument for the native assets mapping uri. Unless we standardize to something like expecting the native assets mapping file to be right next to the kernel file. We had these discussions with Slava all the way in the beginning of this design.

Conceptually this interface should maybe different from what it is now: Dart_InitializeNativeAssetsResolver could take these functions:
LibraryHandle ObtainLibraryForAssetId(const char* asset_id);
void* LookupSymbolInAssetId(LibraryHandle handle, const char* symbol_name);
void CloseLibrary(LibraryHandle handle);

And then the Dart standalone embedder would need to know about how to find the mapping embedded in the right kernel file. So either Dart_InitializeNativeAssetsResolver needs to be called for every isolate group and ObtainLibraryForAssetId would need to be a closure rather than a function pointer which somehow has access to the kernel mapping. Or ObtainLibraryForAssetId needs a param for the isolate group.
And Flutter can just ignore isolate groups and always use the native assets mapping read from a file it can access somewhere.

Notes from offline discussion with @mkustermann:
The embedder API must not have a current isolate, but must have a current isolate group. This avoids the need for passing the isolate group in ObtainLibraryForAssetId. The standalone embedder can access the native assets mapping via https://dart-review.googlesource.com/c/sdk/+/379781, essentially lifting the native assets mapping out of the VM into the standalone embedder. (Addressing https://github.com/dart-lang/sdk/issues/55826 in the process.)

authors: dcharkes mkustermann stuartmorgan


text:
After MacOs 15.0 Update facing this issue

Lexical or Preprocessor Issue (Xcode): Include of non-modular header inside framework module 'firebase_database.FLTFirebaseDatabaseObserveStreamHandler': '/Users/khushal/Projects/Flutter/Inhouse/kunj_fashion/kunj_fashion/ios/Pods/Headers/Public/Firebase/Firebase.h'
/Users/khushal/.pub-cache/hosted/pub.dev/firebase_database-11.1.3/ios/Classes/FLTFirebaseDatabaseObserveStreamHandler.h:3:8
Lexical or Preprocessor Issue (Xcode): Include of non-modular header inside framework module 'firebase_database.FLTFirebaseDatabasePlugin': '/Users/khushal/Projects/Flutter/Inhouse/kunj_fashion/kunj_fashion/ios/Pods/Headers/Public/Firebase/Firebase.h'
/Users/khushal/.pub-cache/hosted/pub.dev/firebase_database-11.1.3/ios/Classes/FLTFirebaseDatabasePlugin.h:3:8
Lexical or Preprocessor Issue (Xcode): Include of non-modular header inside framework module 'firebase_database.FLTFirebaseDatabaseUtils': '/Users/khushal/Projects/Flutter/Inhouse/kunj_fashion/kunj_fashion/ios/Pods/Headers/Public/Firebase/Firebase.h'
/Users/khushal/.pub-cache/hosted/pub.dev/firebase_database-11.1.3/ios/Classes/FLTFirebaseDatabaseUtils.h:3:8
Could not build the application for the simulator.
Error launching application on iPhone 16.
pub file
name:  abc

description: "A new Flutter project."

publish_to: 'none'

version: 1.0.0+1

environment:
  sdk: ^3.5.2

dependencies:
  flutter:
    sdk: flutter

  # Service locator
  get_it: ^8.0.0

  cupertino_icons: ^1.0.8
  firebase_core: ^3.5.0
  firebase_database: ^11.1.3
  get: ^4.6.6
  connectivity_plus: ^6.0.5
  # Local cache
  shared_preferences: ^2.3.2

  # Navigation
  go_router: ^14.2.7

  intl: ^0.19.0

  flutter_svg: ^2.0.10+1
  lottie: ^3.1.2
  firebase_auth: ^5.3.0
  dropdown_search: ^5.0.6

dev_dependencies:
  flutter_test:
    sdk: flutter

  flutter_lints: ^4.0.0

flutter:

  uses-material-design: true
  fonts:
    - family: Poppins
      fonts:
        - asset: assets/fonts/Poppins-Light.ttf
          weight: 100
        - asset: assets/fonts/Poppins-Medium.ttf
          weight: 400
        - asset: assets/fonts/Poppins-Bold.ttf
          weight: 600

    - family: Inter
      fonts:
        - asset: assets/fonts/Inter-Light.ttf
          weight: 100
        - asset: assets/fonts/Inter-Medium.ttf
          weight: 400
        - asset: assets/fonts/Inter-Bold.ttf
          weight: 600

  assets:
    - assets/images/
    - assets/icons/
    - assets/animation/

    ```

Hey @khushal-chothani I got same issue after updating macOS 15. Please update me if you find any solution.

New update here
I've tried to run my App structure code which i'm using for all my apps.
It has not any firebase related dependency so it was working without any issue.
I guess firebase related dependency causing issue but i'm not sure.

Duplicate of 12962

This is indeed a firebase issue. Kindly check https://github.com/firebase/flutterfire/issues/12962 & https://github.com/firebase/flutterfire/issues/13323 for further assistance.
Closing from here
Thank you

source: gharchive/issue

authors: danagbemava-nc julianbraasch khushal-chothani thatskishan

repo: flutter/flutter

license_type: permissive

license_source: github-api


text:
Expose firstFrame callback on iOS

We have this on Android which lets add2app users to get a callback from Flutter on first frame:
https://github.com/flutter/engine/blob/2f19645a761bc2431fe252f0681679352f52548c/shell/platform/android/io/flutter/view/FlutterView.java#L724
We should have an equivalent API on iOS. I could not find any.

Ummm, it seems like I made the APIs asymmetrical initially?
I don't really have a use case for making this event public. It was just used internally to trigger the dismissal of the splash screen while flutter renders its first frame. Though I don't think there's any harm to adding it on iOS either.

I requested more details from the person who originally requested this.  It sounds like the original desire was to be able to show some other Flutter view, but then they discovered initial routes.
@matthew-carroll just asked on flutter-dev to see if anyone is using the Java version.  If no one has a use case, then I'll retract https://github.com/flutter/engine/pull/6135 and won't-fix this.

I'm repurposing this issue to be about exposing a callback for when the splash screen has finished being dismissed.  This should help with automated tests involving screenshot comparisons for add2app cases.

CC @dnfield for visibility

authors: jamesderlin matthew-carroll mehmetf xster


text:
Add new features to Dismissible widget

The Dismissible widget is awesome but has very limited functionality which makes it not usable in many real world applications. Let's consider adding the following features (in order of priority):

Allow onResize() callback to get the direction in which the item was dismissed. This is needed to implement two types of functions depending on swipe direction (e.g. bookmark and delete).

Add an "undo" function to restore the dismissed item by moving it back to its position. This may be useful in case if user wants to undo the dismiss action.

Allow custom animation in the background widgets for example by adding a new callback which gets the slider's position. The animation can be a function of a slider position, like in Google Inbox (resizing the icon on the background).

I was also looking for suggestion number 3: having a callback to get the progress of the dismiss action.
Wondering whether we should split these up into individual tickets though, having separate concerns combined probably just makes this harder to gain traction.

Hi: I'm also looking for suggestion number 1: Allow onResize() callback to get the direction in which the item was dismissed
Thanks

We also miss the ability for _resizeController and _moveController to move together in the same time.
For now it moves THEN it resizes.
It would make it feel faster/smoother to start resizing earlier.
See iOs Gmail swipe to delete animation :)

We also miss the ability for _resizeController and _moveController to move together in the same time.
For now it moves THEN it resizes.
It would make it feel faster/smoother to start resizing earlier.
See iOs Gmail swipe to delete animation :)

It would be great if moveController was exposed, it solves many issues I think

Would love to be able to trigger a dismiss programmatically dismissibleController.dismiss(DismissDirection.up)

Any Update ?

authors: BazinC IlyaMax Velkamhell97 grigy leviatan21 lukepighetti tp


text:
Locale always give en_US

Flutter locale always give en_US on iOS even when system language was set to zh_CN
Both following method give en_US:

Platform.localeName
Localizations.localeOf(context)

Locale works well on Android.
Locale works well on iOS with Flutter version before v0.11.12.
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v1.0.0, on Mac OS X 10.14.2 18C54, locale en-CN)
[✗] Android toolchain - develop for Android devices
    ✗ Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.io/setup/#android-setup for detailed instructions).
      If Android SDK has been installed to a custom location, set $ANDROID_HOME to that location.
      You may also want to add it to your PATH environment variable.

[✓] iOS toolchain - develop for iOS devices (Xcode 10.1)
[!] Android Studio (not installed)
[✓] VS Code (version 1.30.1)
[✓] Connected device (1 available)

Do you have the supported languages listed in Info.plist? https://github.com/flutter/flutter/issues/14128#issuecomment-401028142

@ctrysbita
It would be better if you can post a github project which may help us reproduce this issue.

@zoechi @kangwang1988 Ok, it works well now after I add the localizations to Info.plist.
I think we may have a page for old projects to update when new version of framework have some breaking changes.

authors: ctrysbita kangwang1988 zoechi


text:
AAPT: error: resource android:attr/fontVariationSettings not found after Flutter Upgrade

My flutter application used to work perfectly until recently I decided to upgrade to Flutter version 1.0.0. After upgrade I'm getting the below errors during compilation in one of my project:
AAPT: error: resource android:attr/fontVariationSettings not found.
AAPT: error: resource android:attr/ttcIndex not found.

FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:processDevelopmentDebugResources'.
> Failed to process resources, see aapt output above for details.

I've tried many things I can find in Google but none of them works. Appreciates for any help here.

My Compiledsdkversioin is 28 only. But still facing the same issue.
* What went wrong:

Execution failed for task ':url_launcher:verifyReleaseResources'.

> java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource linking failed

  D:\flutter-projects\project1\build\url_launcher\intermediates\res\merged\release\values\values.xml:236: error: resource android:attr/fontVariationSettings not found.

  D:\flutter-projects\project1\build\url_launcher\intermediates\res\merged\release\values\values.xml:237: error: resource android:attr/ttcIndex not found.

  error: failed linking references.

I upgraded yesterday to 1.12.13. I now have exactly this issue. More info here  https://github.com/flutter/flutter/issues/46881

I'm also facing the same issue when I run flutter build apk
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':thumbnails:verifyReleaseResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > Android resource linking failed
     /Users/divyanshub024/.gradle/caches/transforms-2/files-2.1/8ef0dd1b827b6b28c1e9211227fa2d4c/core-1.0.0/res/values/values.xml:57:5-88:25: AAPT: error: resource android:attr/fontVariationSettings not found.

     /Users/divyanshub024/.gradle/caches/transforms-2/files-2.1/8ef0dd1b827b6b28c1e9211227fa2d4c/core-1.0.0/res/values/values.xml:57:5-88:25: AAPT: error: resource android:attr/ttcIndex not found.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2m 56s

I upgraded yesterday to 1.12.13. I now have exactly this issue.

I upgraded yesterday to 1.12.13. I have the same issue as well

guys, i facing this issue too, can i know how you guys fix it?

I had this issue with a couple of plugins that my project uses:

devicelocale
vibrate

The issue was gone once these plugins were updated to use compiledsdkversioin set to 28.

my fix here https://github.com/adee42/flutter_keyboard_visibility/issues/42#issuecomment-566656630
CC @nkmswot

If anyone has this issue with some package

In your project folder go to External libraries
Locate the library that raised the issue
Open it's build.gradle(app)
update the compileSdkVersion to 28

If anyone has this issue with some package

In your project folder go to External libraries
Locate the library that raised the issue
Open it's build.gradle(app)
update the compileSdkVersion to 28

Didnt work for me. Didnt find solution already. Any suggestions ?
Plus, android studio throws exception 'Cannot resolve symbol GradleException' at line 11 , but i ignore that one.

I fixed this error by changing compileSdkVersion from 27 to 28 in one of the dependencies. So check build.gradle file in the repo of every dependency that you use.

If anyone has this issue with some package

In your project folder go to External libraries
Locate the library that raised the issue
Open it's build.gradle(app)
update the compileSdkVersion to 28

Thank you. It solved the issue

I'm also facing the same issue when I run flutter build apk
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':thumbnails:verifyReleaseResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > Android resource linking failed
     /Users/divyanshub024/.gradle/caches/transforms-2/files-2.1/8ef0dd1b827b6b28c1e9211227fa2d4c/core-1.0.0/res/values/values.xml:57:5-88:25: AAPT: error: resource android:attr/fontVariationSettings not found.

     /Users/divyanshub024/.gradle/caches/transforms-2/files-2.1/8ef0dd1b827b6b28c1e9211227fa2d4c/core-1.0.0/res/values/values.xml:57:5-88:25: AAPT: error: resource android:attr/ttcIndex not found.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2m 56s

Do you get solution?

My failure appears to be caused by: https://github.com/rickyazhari/root_checker/blob/master/android/build.gradle#L25

I remove all unused plugins from External Libraries folder and pub.yaml to solve the problem.

authors: AleksMx ChiHwe adrianvintu alexda12 ayham95 bobanminic96 divyanshub024 dsmailpuneet gmlewis gopalsgs hatted miguelcmedeiros nkmswot sarinupreti zanecidan


text:
[google_maps_flutter] Google Maps projection

Hi there,
First of all, I wanna thanks you for all the work you are doing with Flutter and the Google Maps Plugin particulary. Have been using it for around three weeks now and really love it.
Still I would like to know, is there anyway to make the Google Maps projection available through the plugin ?
I have done some digging and looks like Projection are already available in the android .java file and the ios .m file too.
Thanks for your feedbacks,
PS : I checked before posting and (except if I am wrong) didn't find a duplicate to this request

Any updates on this?

Nope but found a workaround to fix this.
Basically used this solution found on StackOverflow and Google Documentation :
https://developers.google.com/maps/documentation/javascript/examples/map-coordinates
https://stackoverflow.com/questions/23457916/how-to-get-latitude-and-longitude-bounds-from-google-maps-x-y-and-zoom-parameter
Hope it will help

Sorry for me question but, can Projections solve my problem?

@SDRuiz: Nope. Projection will just help you to get the equivalent of your GPS coordinates into pixel coordinates (or vice versa).
In your case, looks like you are trying to display an route retrieve from Google Service Right ?
If show, the encoded_polyline retrieved is the reason why you have it displayed this way.
For each sub route of the route, you have a more precise encoded_polyline you should use instead if you wanna have a better render of the route.
If you aren't user Google Service, you can subscrible to the snap to road service which works as explained (follow the link ...) It is a paid service.
Snap to Road description :  https://developers.google.com/maps/documentation/roads/snap
Snap to Road pricing : https://developers.google.com/maps/documentation/roads/usage-and-billing
Hope it helps

@aarocorp you are my very best friend rigth now...I really appretiate your response. I hit the Google Directions API and get the Response, extract the legs of the route and generate the polyline. Maybe the google_maps_flutter polyline's is not finish or something like that, because in Android work better or resolve the route better. I will review the API response to see if I been missed some info. Thanks again!

my please.
Example taken from : https://developers.google.com/maps/documentation/directions/intro#sample-response
routes": [ {
    "summary": "I-40 W",
    "legs": [ {
      "steps": [ {
        "travel_mode": "DRIVING",
        "start_location": {
          "lat": 41.8507300,
          "lng": -87.6512600
        },
        "end_location": {
          "lat": 41.8525800,
          "lng": -87.6514100
        },
        "polyline": {
          "points": "a~l~Fjk~uOwHJy@P"
        },
        "duration": {
          "value": 19,
          "text": "1 min"
        },
        "html_instructions": "Head \u003cb\u003enorth\u003c/b\u003e on \u003cb\u003eS
        Morgan St\u003c/b\u003e toward \u003cb\u003eW Cermak Rd\u003c/b\u003e",
        "distance": {
          "value": 207,
          "text": "0.1 mi"
        }
      },
      ...
      ... additional steps of this leg
    ...
    ... additional legs of this route
      "duration": {
        "value": 74384,
        "text": "20 hours 40 mins"
      },
      "distance": {
        "value": 2137146,
        "text": "1,328 mi"
      },
      "start_location": {
        "lat": 35.4675602,
        "lng": -97.5164276
      },
      "end_location": {
        "lat": 34.0522342,
        "lng": -118.2436849
      },
      "start_address": "Oklahoma City, OK, USA",
      "end_address": "Los Angeles, CA, USA"
    } ],
    "copyrights": "Map data ©2010 Google, Sanborn",
    "overview_polyline": {
      "points": "a~l~Fjk~uOnzh@vlbBtc~@tsE`vnApw{A`dw@~w\\|tNtqf@l{Yd_Fblh@rxo@b}@xxSfytA
      blk@xxaBeJxlcBb~t@zbh@jc|Bx}C`rv@rw|@rlhA~dVzeo@vrSnc}Axf]fjz@xfFbw~@dz{A~d{A|zOxbrBbdUvpo@`
      cFp~xBc`Hk@nurDznmFfwMbwz@bbl@lq~@loPpxq@bw_@v|{CbtY~jGqeMb{iF|n\\~mbDzeVh_Wr|Efc\\x`Ij{kE}mAb
      ~uF{cNd}xBjp]fulBiwJpgg@|kHntyArpb@bijCk_Kv~eGyqTj_|@`uV`k|DcsNdwxAott@r}q@_gc@nu`CnvHx`k@dse
      @j|p@zpiAp|gEicy@`omFvaErfo@igQxnlApqGze~AsyRzrjAb__@ftyB}pIlo_BflmA~yQftNboWzoAlzp@mz`@|}_
      @fda@jakEitAn{fB_a]lexClshBtmqAdmY_hLxiZd~XtaBndgC"
    },
    "warnings": [ ],
    "waypoint_order": [ 0, 1 ],
    "bounds": {
      "southwest": {
        "lat": 34.0523600,
        "lng": -118.2435600
      },
      "northeast": {
        "lat": 41.8781100,
        "lng": -87.6297900
      }
    }
  } ]

Don't use overview_polyline,
use instead the points within each step > polyline
{
      "steps": [ {
        "travel_mode": "DRIVING",
        "start_location": {
          "lat": 41.8507300,
          "lng": -87.6512600
        },
        "end_location": {
          "lat": 41.8525800,
          "lng": -87.6514100
        },
        "polyline": {
          "points": "a~l~Fjk~uOwHJy@P"
        },
        "duration": {
          "value": 19,
          "text": "1 min"
        },
        "html_instructions": "Head \u003cb\u003enorth\u003c/b\u003e on \u003cb\u003eS
        Morgan St\u003c/b\u003e toward \u003cb\u003eW Cermak Rd\u003c/b\u003e",
        "distance": {
          "value": 207,
          "text": "0.1 mi"
        }
      },

@aarocorp yea, i'd tried that, but is the same as the lat, long start and end.
I checked that you told me about snap to roud, it's really great in near points :)
I post a feedback to google told them my problem, and especting what API can help me to solve this issue.
Thanks again, I really appreciate your help!

@SDRuiz I am really surprised by the result on your size. So lets me sum it up again :

You are using Google Direction API which give you the route from a point A to a point B. Correct ?
For the route retrieved, you loop into the steps and get the polyline > points within each. Correct ?
If so it is supposed to work. Have anything against the Snap Road API but depending on the calls you will be making it might end up costly (especially because you are already using the direction API which already have the information you need)
Can you share the part of code you made ?

@SDRuiz even simplier. Below my code. Have a look and adapt it to yours :
Decoding of polyline
gmdir.Route route =
          directions.routes.length > 0 ? directions.routes[0] : null;

      if (route == null) return null;

      var legs = directions.routes[0].legs;
      for (int i = 0; i < legs.length; i++) {
        var steps = legs[i].steps;
          points.addAll(
              _decodePolyline(legs[i].steps[j].polyline.points));
        }
      }

_decodePolyline
List<gmf.LatLng> _decodePolyline(String encoded) {
    List<gmf.LatLng> points = new List<gmf.LatLng>();
    int index = 0, len = encoded.length;
    int lat = 0, lng = 0;
    while (index < len) {
      int b, shift = 0, result = 0;
      do {
        b = encoded.codeUnitAt(index++) - 63;
        result |= (b & 0x1f) << shift;
        shift += 5;
      } while (b >= 0x20);
      int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
      lat += dlat;
      shift = 0;
      result = 0;
      do {
        b = encoded.codeUnitAt(index++) - 63;
        result |= (b & 0x1f) << shift;
        shift += 5;
      } while (b >= 0x20);
      int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
      lng += dlng;
      gmf.LatLng p = new gmf.LatLng(lat / 1E5, lng / 1E5);
      points.add(p);
    }
    return points;
  }

 Legend
import 'package:google_maps_flutter/google_maps_flutter.dart' as gmf;
import 'package:google_maps_webservice/directions.dart' as gmdir;

You are using Google Direction API which give you the route from a point A to a point B. Correct ?

Yes, I am doing that.

For the route retrieved, you loop into the steps and get the polyline > points within each. Correct ?

I'm working whit LatLng, to draw the polyline, so I get the start and end coordinates for every step and added to the set like this:
import 'package:google_maps_flutter/google_maps_flutter.dart' as flutter;
import 'package:google_maps_webservice/directions.dart' as google;

_mapsApiProvider
	.getDirections(origin, destination, points)
	.then((google.DirectionsResponse response) {
		List<google.Leg> legs = response.routes[0].legs;
		List<flutter.LatLng> ccc = List();
		for (var leg in legs) {
			List<google.Step> steps = leg.steps;
			print(steps.toString());
			for (final i in steps) {
				distance += i.distance.value;
				duration += i.duration.value;
				ccc.add(flutter.LatLng(i.startLocation.lat, i.startLocation.lng));
				ccc.add(flutter.LatLng(i.endLocation.lat, i.endLocation.lng));
			}
		}
		getSnapToRoad(ccc).then((pointList) {
		setState(
			() {
				_markers.clear();
				for (var point in itinerary) {
					_markers.add(
						flutter.Marker(
							markerId: flutter.MarkerId("parada ${point.latitude}"),
							position: flutter.LatLng(point.latitude, point.longitude),
							infoWindow: flutter.InfoWindow(
							title: point.address, snippet: point.province),
						),
					);
				}
				_polyline.clear();
				_polyline.add(
					flutter.Polyline(
						polylineId: flutter.PolylineId("route"),
						points: pointList,
						width: 2,
						color: Colors.red,
						geodesic: true,
						jointType: flutter.JointType.round,
					),
				);
			});
		}

Future<List<flutter.LatLng>> getSnapToRoad(List<flutter.LatLng> ccc) async {
    List<flutter.LatLng> points = new List();
    String coordinates = "";
    for (flutter.LatLng latlng in ccc) {
      coordinates += "${latlng.latitude},${latlng.longitude}|";
    }
    var snapResponse = await _mapsApiProvider
        .getSnapToRoads(coordinates.substring(0, coordinates.length - 2));
    for (var snap in snapResponse.snappedPoints) {
      flutter.LatLng location =
          new flutter.LatLng(snap.location.latitude, snap.location.longitude);
      points.add(location);
    }
    return points;
  }

If so it is supposed to work. Have anything against the Snap Road API but depending on the calls you will be making it might end up costly (especially because you are already using the direction API which already have the information you need)
Can you share the part of code you made ?

Sorry for this mess, I'm not using any StateManagment or Pattern to probe this!

@SDRuiz : Hey. Sorry for the silence. Been busy lately. Take time to have a look and let you know if I find something 👍

@aarocorp NP man, thanks a lot for your help.
Do you know or integrate Geofence for flutter?
can I add you to Slack, Skype, Hangout or some other chat? :)

@SDRuiz sure thing.
My Skype account : aaro188
Will we talk about your geofence question there if you don't mind 👍

I think projection has been added a few days ago.
Not entirely the same issue, but does someone know if I can use some projection function to check if a given gps-coordinate is within the boundaries of a polygon (also gps-coordinates)?

yes, projections are supposed to be in 0.5.21+4 (September 25). I think it's safe to close the issue.
If you disagree or the feature doesn't solve the problem, please comment, I will re-open it right away.

@SDRuiz you can solved the problem with the lines? i try but not found the solution.

authors: BondarenkoStas Juan-JDGroup RevanScript SDRuiz aarocorp joknjokn


text:
[android_alarm_manager] stop working after flutter upgrade

After upgrade Flutter yesterday (2019-07-11), android_alarm_manager (0.4.1+6)  crashed my App as soon is opened ,  not useful information was reported on logcat , just that app crashed
but i moved the initialization when pressing a button, still crashing but i got this Callstack:
E/AndroidRuntime(21658): java.lang.RuntimeException: An error occurred while executing doInBackground()
E/AndroidRuntime(21658): 	at android.os.AsyncTask$3.done(AsyncTask.java:366)
E/AndroidRuntime(21658): 	at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
E/AndroidRuntime(21658): 	at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
E/AndroidRuntime(21658): 	at java.util.concurrent.FutureTask.run(FutureTask.java:271)
E/AndroidRuntime(21658): 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/AndroidRuntime(21658): 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/AndroidRuntime(21658): 	at java.lang.Thread.run(Thread.java:784)
E/AndroidRuntime(21658): Caused by: java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: AsyncTask #5
E/AndroidRuntime(21658): 	at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:794)
E/AndroidRuntime(21658): 	at io.flutter.embedding.engine.FlutterJNI.dispatchPlatformMessage(FlutterJNI.java:684)
E/AndroidRuntime(21658): 	at io.flutter.embedding.engine.dart.DartMessenger.send(DartMessenger.java:80)
E/AndroidRuntime(21658): 	at io.flutter.embedding.engine.dart.DartExecutor.send(DartExecutor.java:189)
E/AndroidRuntime(21658): 	at io.flutter.view.FlutterNativeView.send(FlutterNativeView.java:155)
E/AndroidRuntime(21658): 	at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:98)
E/AndroidRuntime(21658): 	at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:84)
E/AndroidRuntime(21658): 	at io.flutter.plugins.androidalarmmanager.AlarmService.invokeCallbackDispatcher(AlarmService.java:170)
E/AndroidRuntime(21658): 	at io.flutter.plugins.androidalarmmanager.AlarmService.onHandleWork(AlarmService.java:151)
E/AndroidRuntime(21658): 	at androidx.core.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:392)
E/AndroidRuntime(21658): 	at androidx.core.app.JobIntentService$CommandProcessor.doInBackground(JobIntentService.java:383)
E/AndroidRuntime(21658): 	at android.os.AsyncTask$2.call(AsyncTask.java:345)
E/AndroidRuntime(21658): 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
E/AndroidRuntime(21658): 	... 3 more

Flutter doctor

[v] Flutter (Channel stable, v1.7.8+hotfix.3, on Microsoft Windows [Version 10.0.17763.557], locale en-US)
    • Flutter version 1.7.8+hotfix.3 at G:\data\SDKs\flutter
    • Framework revision b712a172f9 (3 days ago), 2019-07-09 13:14:38 -0700
    • Engine revision 54ad777fd2
    • Dart version 2.4.0

[v] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at G:\data\Programs\Android\sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • ANDROID_HOME = G:\data\Programs\Android\sdk
    • Java binary at: C:\Program Files\Java\jdk1.8.0_162\bin\java
    • Java version Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
    • All Android licenses accepted.

[v] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[!] Android Studio (not installed)

Application.java

package com.example.helloworld;

import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;

public class Application extends FlutterApplication implements PluginRegistrantCallback {
  @Override
  public void onCreate() {
    super.onCreate();
    AlarmService.setPluginRegistrant(this);
  }

  @Override
  public void registerWith(PluginRegistry registry) {
    GeneratedPluginRegistrant.registerWith(registry);
  }
}

MainActivity.java

package com.example.helloworld;

import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;

public class MainActivity extends FlutterActivity {
	public static final String TAG = "LockerMainActivity";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GeneratedPluginRegistrant.registerWith(this);
  }
}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworld">

    <!-- The INTERNET permission is required for development. Specifically,
         flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <application
        android:name=".Application"
        android:label="hello_world"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <!-- android_alarm_manager -->
        <service
            android:name="io.flutter.plugins.androidalarmmanager.AlarmService"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:exported="false"/>
        <receiver
            android:name="io.flutter.plugins.androidalarmmanager.AlarmBroadcastReceiver"
            android:exported="false"/>
        <receiver
            android:name="io.flutter.plugins.androidalarmmanager.RebootBroadcastReceiver"
            android:enabled="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"></action>
            </intent-filter>
        </receiver>
    </application>
</manifest>

main.dart

import 'dart:isolate';
import 'package:flutter/material.dart';
import 'package:android_alarm_manager/android_alarm_manager.dart';

import 'ui/home.dart';

void printHello() {
  final DateTime now = DateTime.now();
  final int isolateId = Isolate.current.hashCode;
  print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
}

main() async {
  final int helloAlarmID = 0;
  await AndroidAlarmManager.initialize(); // <<-------- MAKE IT CRASH
  runApp(MyApp());
  await AndroidAlarmManager.periodic(const Duration(minutes: 1), helloAlarmID, printHello);
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'MyApp',
        theme: ThemeData(
          primarySwatch: Colors.purple,
        ),
        routes: {
          '/home': (_) => HomeScreen(),
        },
        home: HomeScreen();
  }
}

Those of us using threads other than the UI are still battling for a fix in the issue below. In the mean time you can revert to a previous flutter version. I used v1.5.3.
https://github.com/flutter/flutter/issues/34993

I believe this is a duplicate of https://github.com/flutter/flutter/issues/32976 which was fixed by https://github.com/flutter/plugins/pull/1641 the fix is available starting version 0.4.1+7 of the plugin.
Can you try with the latest version of the plugin?

@amirh Hello, i've tried already with 0.4.1+7 and 0.4.1+8 , and the issue still persists

@amirh  i did a new test, and it seems to be working for me now, i will close it , and open it in the future if happend again, thanks

@hgouveia @amirh The same issue is still happening in Flutter v1.22.5 Stable channel

authors: MichealReed Udit-singh amirh hgouveia


text:
Using Container and/or BoxDecoration color property error is confusing

If color: is specified as Container property and color: is used with BoxDecoration it gives an error which is well and good, except error is at runtime not caught by IDE or compiler.
Also the error should say 'Cannot provide both a color and a decoration.The color argument is just a shorthand for "decoration: new BoxDecoration(color: color). If decoration is used color MUST ONLY be specified with decoration.
In the attached examples error is thrown at runtime
----error example 1---
body: Container(
        width: 50.0,
        height: 50.0,
        color: Colors.blue, //error as well not quite expected
        decoration: BoxDecoration(
          //     color: Colors.red,
          border: Border.all(
              color: Colors.green, width: 5.0, style: BorderStyle.solid),
        ),
      ),
    );

----- error example 2---
body: Container(
        width: 50.0,
        height: 50.0,
        color: Colors.blue, //expected error
        decoration: BoxDecoration(
        color: Colors.red,
          border: Border.all(
              color: Colors.green, width: 5.0, style: BorderStyle.solid),
        ),
      ),
    );

------Error  Message---
I/flutter (20774): The following assertion was thrown building HomePage(dirty, state: _HomePageState#a88dc):
I/flutter (20774): Cannot provide both a color and a decoration
I/flutter (20774): The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".
I/flutter (20774): 'package:flutter/src/widgets/container.dart':
I/flutter (20774): Failed assertion: line 271 pos 15: 'color == null || decoration == null'
I/flutter (20774):
I/flutter (20774): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (20774): more information in this error message to help you determine and fix the underlying cause.
I/flutter (20774): In either case, please report this assertion by filing a bug on GitHub:

------------------Example----
import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(
    home: new HomePage(),
  ));
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => new _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        width: 50.0,
        height: 50.0,
        color: Colors.blue,
        decoration: BoxDecoration(
          //     color: Colors.red,
          border: Border.all(
              color: Colors.green, width: 5.0, style: BorderStyle.solid),
        ),
      ),
    );
  }
}

I believe this is fixed. Running all of the code snippets above produces a much clearer error message now:

authors: Piinks sjghose


text:
IOS: setTimeout in javascript does not complete if webview_flutter is hidden by Offstage widget

I have seen this issue on a physical iPhone 5S running IOS 12.3.1, but not on iPhone Simulator (currently only IOS 12.2 is available) or on Android. Briefly, if the WebView widget is wrapped in an Offstage widget so that it can be hidden, and WebViewController.evaluateJavascript is used to execute javascript containing a setTimeout call, the timeout never returns as long as the WebView widget is hidden. It does complete when the WebView is shown again, and runs normally if it is invoked when the WebView is showing.
See below for flutter doctor and main.dart of a test app that illustrates this issue.
To reproduce the bug:

Create a new flutter app project, aka "test app".
Paste in new content for main.dart from the webview_flutter example project on Github, and update pubspec.yaml with a dependency for webview_flutter 0.3.10+3 (the current version).
Verify that the test app runs.
Modify test app (see code for main.dart below) by wrapping the WebView widget in an Offstage widget to allow it to be shown or hidden.
Add to the sample menu a new item to show or hide the webview, with a corresponding action that executes a callback to WebViewExampleState to toggle the visibility of the webview.
Add a second new menu item to execute test javascript, with an action that invokes WebViewController.evaluateJavascript to execute the following code:

Toaster.postMessage("3 second delay begins...");
		setTimeout(()=>{
  		Toaster.postMessage("Delay ends.");
  	}, 3000);

Run the test app on the IOS simulator to confirm that this javascript executes properly with the webview both showing and hidden.
Confirm that when the test app is run on a physical iPhone running IOS 12.3.1 that the javascript timeout never completes when the webview is hidden. This is the bug.
Confirm that the timeout completes when the webview is shown again.

flutter doctor
flutter doctor -v
[✓] Flutter (Channel stable, v1.7.8+hotfix.3, on Mac OS X 10.14.5 18F132, locale en-US)
    • Flutter version 1.7.8+hotfix.3 at /Users/alan/Documents/util/flutter
    • Framework revision b712a172f9 (9 days ago), 2019-07-09 13:14:38 -0700
    • Engine revision 54ad777fd2
    • Dart version 2.4.0

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /Users/alan/Library/Android/sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-28, build-tools 28.0.3
    • ANDROID_HOME = /Users/alan/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 10.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.2.1, Build version 10E1001
    • CocoaPods version 1.7.4

[✓] iOS tools - develop for iOS devices
    • ios-deploy 1.9.4

[✓] Android Studio (version 3.4)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 37.0.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

[✓] IntelliJ IDEA Community Edition (version 2018.3.3)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 31.3.4
    • Dart plugin version 183.5153.38

[✓] Connected device (2 available)
    • Alan’s iPhone 5S • fb2c341f9cecedf031922c7a9f3977426a476bf6 • ios • iOS 12.3.1
    • iPhone 8 Plus    • B25D2A11-1051-4FFB-B54C-BB1DEF991EE7     • ios • com.apple.CoreSimulator.SimRuntime.iOS-12-2 (simulator)

• No issues found!

Here's main.dart. This is just the example for webview_flutter with a couple of extra menu items to (1) show/hide the webview; and (2) execute javascript that contains a setTimeout.
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() => runApp(MaterialApp(home: WebViewExample()));

const String kNavigationExamplePage = '''
<!DOCTYPE html>
<title>Navigation Delegate Example</title>

The navigation delegate is set to block navigation to the youtube website.

https://www.youtube.com/

https://www.google.com/

''';

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  final Completer<WebViewController> _controller =
  Completer<WebViewController>();

  bool _showWebView = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter WebView example'),
        // This drop down menu demonstrates that Flutter widgets can be shown over the web view.
        actions: <Widget>[
          NavigationControls(_controller.future),
          SampleMenu(_controller.future, ()=>_showHideWebView()),
        ],
      ),
      // We're using a Builder here so we have a context that is below the Scaffold
      // to allow calling Scaffold.of(context) so we can show a snackbar.
      body: Builder(builder: (BuildContext context) {
        return Offstage(
          offstage: ! _showWebView,
          child: WebView(
            initialUrl: 'https://flutter.dev',
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (WebViewController webViewController) {
              _controller.complete(webViewController);
            },
            // TODO(iskakaushik): Remove this when collection literals makes it to stable.
            // ignore: prefer_collection_literals
            javascriptChannels: <JavascriptChannel>[
              _toasterJavascriptChannel(context),
            ].toSet(),
            navigationDelegate: (NavigationRequest request) {
              if (request.url.startsWith('https://www.youtube.com/')) {
                print('blocking navigation to $request}');
                return NavigationDecision.prevent;
              }
              print('allowing navigation to $request');
              return NavigationDecision.navigate;
            },
            onPageFinished: (String url) {
              print('Page finished loading: $url');
            },
          ),
        );
      }),
      floatingActionButton: favoriteButton(),
    );
  }

  // Toggle webview visibility
  void _showHideWebView() {
    setState((){
      _showWebView = !_showWebView;
    });
  }

  JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'Toaster',
        onMessageReceived: (JavascriptMessage message) {
          Scaffold.of(context).showSnackBar(
            SnackBar(content: Text(message.message)),
          );
        });
  }

  Widget favoriteButton() {
    return FutureBuilder<WebViewController>(
        future: _controller.future,
        builder: (BuildContext context,
            AsyncSnapshot<WebViewController> controller) {
          if (controller.hasData) {
            return FloatingActionButton(
              onPressed: () async {
                final String url = await controller.data.currentUrl();
                Scaffold.of(context).showSnackBar(
                  SnackBar(content: Text('Favorited $url')),
                );
              },
              child: const Icon(Icons.favorite),
            );
          }
          return Container();
        });
  }
}

enum MenuOptions {
  showUserAgent,
  listCookies,
  clearCookies,
  addToCache,
  listCache,
  clearCache,
  navigationDelegate,
  hideShowWebview,
  executeTestJavascript,
}

class SampleMenu extends StatelessWidget {
  void Function() showHideWebPageCallback;

  SampleMenu(this.controller, void Function() this.showHideWebPageCallback);

  final Future<WebViewController> controller;
  final CookieManager cookieManager = CookieManager();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
      future: controller,
      builder:
          (BuildContext context, AsyncSnapshot<WebViewController> controller) {
        return PopupMenuButton<MenuOptions>(
          onSelected: (MenuOptions value) {
            switch (value) {
              case MenuOptions.showUserAgent:
                _onShowUserAgent(controller.data, context);
                break;
              case MenuOptions.listCookies:
                _onListCookies(controller.data, context);
                break;
              case MenuOptions.clearCookies:
                _onClearCookies(context);
                break;
              case MenuOptions.addToCache:
                _onAddToCache(controller.data, context);
                break;
              case MenuOptions.listCache:
                _onListCache(controller.data, context);
                break;
              case MenuOptions.clearCache:
                _onClearCache(controller.data, context);
                break;
              case MenuOptions.navigationDelegate:
                _onNavigationDelegateExample(controller.data, context);
                break;
              case MenuOptions.hideShowWebview:
                _onHideShowWebview(controller.data, context);
                break;
              case MenuOptions.executeTestJavascript:
                _onExecuteTestJavascript(controller.data, context);
                break;
            }
          },
          itemBuilder: (BuildContext context) => <PopupMenuItem<MenuOptions>>[
            PopupMenuItem<MenuOptions>(
              value: MenuOptions.showUserAgent,
              child: const Text('Show user agent'),
              enabled: controller.hasData,
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.listCookies,
              child: Text('List cookies'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.clearCookies,
              child: Text('Clear cookies'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.addToCache,
              child: Text('Add to cache'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.listCache,
              child: Text('List cache'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.clearCache,
              child: Text('Clear cache'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.navigationDelegate,
              child: Text('Navigation Delegate example'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.hideShowWebview,
              child: Text('Hide/Show webview'),
            ),
            const PopupMenuItem<MenuOptions>(
              value: MenuOptions.executeTestJavascript,
              child: Text('Execute test javascript'),
            ),
          ],
        );
      },
    );
  }

  void _onShowUserAgent(
      WebViewController controller, BuildContext context) async {
    // Send a message with the user agent string to the Toaster JavaScript channel we registered
    // with the WebView.
    controller.evaluateJavascript(
        'Toaster.postMessage("User Agent: " + navigator.userAgent);');
  }

  void _onListCookies(
      WebViewController controller, BuildContext context) async {
    final String cookies =
    await controller.evaluateJavascript('document.cookie');
    Scaffold.of(context).showSnackBar(SnackBar(
      content: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          const Text('Cookies:'),
          _getCookieList(cookies),
        ],
      ),
    ));
  }

  void _onAddToCache(WebViewController controller, BuildContext context) async {
    await controller.evaluateJavascript(
        'caches.open("test_caches_entry"); localStorage["test_localStorage"] = "dummy_entry";');
    Scaffold.of(context).showSnackBar(const SnackBar(
      content: Text('Added a test entry to cache.'),
    ));
  }

  void _onListCache(WebViewController controller, BuildContext context) async {
    await controller.evaluateJavascript('caches.keys()'
        '.then((cacheKeys) => JSON.stringify({"cacheKeys" : cacheKeys, "localStorage" : localStorage}))'
        '.then((caches) => Toaster.postMessage(caches))');
  }

  void _onClearCache(WebViewController controller, BuildContext context) async {
    await controller.clearCache();
    Scaffold.of(context).showSnackBar(const SnackBar(
      content: Text("Cache cleared."),
    ));
  }

  void _onClearCookies(BuildContext context) async {
    final bool hadCookies = await cookieManager.clearCookies();
    String message = 'There were cookies. Now, they are gone!';
    if (!hadCookies) {
      message = 'There are no cookies.';
    }
    Scaffold.of(context).showSnackBar(SnackBar(
      content: Text(message),
    ));
  }

  void _onNavigationDelegateExample(
      WebViewController controller, BuildContext context) async {
    final String contentBase64 =
    base64Encode(const Utf8Encoder().convert(kNavigationExamplePage));
    controller.loadUrl('data:text/html;base64,$contentBase64');
  }

  void _onHideShowWebview(WebViewController controller, BuildContext context) {
    this.showHideWebPageCallback();
  }

  void _onExecuteTestJavascript(WebViewController controller, BuildContext context) async {
    await controller.evaluateJavascript(
      """
      Toaster.postMessage("3 second delay begins...");
      setTimeout(()=>{
        Toaster.postMessage("Delay ends.");
        }, 3000);
      """
    );
  }

  Widget _getCookieList(String cookies) {
    if (cookies == null || cookies == '""') {
      return Container();
    }
    final List<String> cookieList = cookies.split(';');
    final Iterable<Text> cookieWidgets =
    cookieList.map((String cookie) => Text(cookie));
    return Column(
      mainAxisAlignment: MainAxisAlignment.end,
      mainAxisSize: MainAxisSize.min,
      children: cookieWidgets.toList(),
    );
  }
}

class NavigationControls extends StatelessWidget {
  const NavigationControls(this._webViewControllerFuture)
      : assert(_webViewControllerFuture != null);

  final Future<WebViewController> _webViewControllerFuture;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
      future: _webViewControllerFuture,
      builder:
          (BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
        final bool webViewReady =
            snapshot.connectionState == ConnectionState.done;
        final WebViewController controller = snapshot.data;
        return Row(
          children: <Widget>[
            IconButton(
              icon: const Icon(Icons.arrow_back_ios),
              onPressed: !webViewReady
                  ? null
                  : () async {
                if (await controller.canGoBack()) {
                  controller.goBack();
                } else {
                  Scaffold.of(context).showSnackBar(
                    const SnackBar(content: Text("No back history item")),
                  );
                  return;
                }
              },
            ),
            IconButton(
              icon: const Icon(Icons.arrow_forward_ios),
              onPressed: !webViewReady
                  ? null
                  : () async {
                if (await controller.canGoForward()) {
                  controller.goForward();
                } else {
                  Scaffold.of(context).showSnackBar(
                    const SnackBar(
                        content: Text("No forward history item")),
                  );
                  return;
                }
              },
            ),
            IconButton(
              icon: const Icon(Icons.replay),
              onPressed: !webViewReady
                  ? null
                  : () {
                controller.reload();
              },
            ),
          ],
        );
      },
    );
  }
}

@admarwick Can you please try it with current flutter stable and with master, is it the same?

@BondarenkoStas: Yes, the same problem occurs with both the current master and stable branches of flutter. The master version was
Flutter (Channel master, v1.10.7-pre.73, on Mac OS X 10.14.6 18G103, locale en-US)

and the webview_flutter version was 0.3.14+1.

Oops, closed in error. Sorry.

I have the same problem.
Flutter (Channel stable, v1.12.13+hotfix.8, on Mac OS X 10.15.3 19D76, locale zh-Hans-CN)

Hi all
if you are experiencing the issue with the latest stable version of flutter
and the latest version of webview_flutter
could please provide your update flutter doctor -v ,
your flutter run --verbose,
your pubspec.yaml
and a reproducible minimal code sample.
Thank you

@iapicca
Thank you for your reply.
I tried to build a reproducible minimal code sample. But setTimeout works.
I couldn't see the script execution error log in webview, Make me misunderstand.

Could everyone who still has this problem please file a new issue with the exact descriptions
what happens, logs and the output of 'flutter doctor -v' please.
All system setups can be slightly different so it's always better to open new issues and reference
related issues
Thank you

authors: BondarenkoStas TahaTesser admarwick iapicca zzetao


text:
Keyboard closes if something rebuilds underneath it

Steps to Reproduce

... Run the gist here https://gist.github.com/matejthetree/198c6c7463bd2a1a138b70f4b1175f48
Don't forget to add the plugin to the yaml.
keyboard_visibility: 0.5.6
... Press the textfield
... The keyboard will close automatically.

If you comment out line 63+
            _keyboardOn
                ? Container()
                : Text('keyboard is off'), //comment this line to make it work

Then, everything works.
How to go around this?
flutter doctor -v(base) stablos-MacBook-Pro:set_state_tf korijen$ flutter doctor -v
[✓] Flutter (Channel master, v1.10.3-pre.47, on Mac OS X 10.14.6 18G95, locale en-HR)
    • Flutter version 1.10.3-pre.47 at /Users/korijen/Work/SDKs/flutter
    • Framework revision 928245d07c (3 hours ago), 2019-09-16 06:14:41 -0400
    • Engine revision 224ab48f1b
    • Dart version 2.6.0 (build 2.6.0-dev.0.0 f8f0b845c2)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.1)
    • Android SDK at /Users/korijen/Work/SDKs/android
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.1
    • ANDROID_HOME = /Users/korijen/Work/SDKs/android
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 10.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 10.3, Build version 10G8
    • CocoaPods version 1.7.5

[✓] Android Studio (version 3.5)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 38.2.3
    • Dart plugin version 191.8423
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)

[✓] IntelliJ IDEA Ultimate Edition (version 2019.2.1)
    • IntelliJ at /Applications/IntelliJ IDEA.app
    • Flutter plugin version 38.2.4
    • Dart plugin version 192.6262.58

[✓] IntelliJ IDEA Community Edition (version 2019.1.3)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 37.1.3
    • Dart plugin version 191.7830

[!] VS Code (version 1.37.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    ✗ Flutter extension not installed; install from
      https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (1 available)
    • Android SDK built for x86 • emulator-5554 • android-x86 • Android 10 (API 29) (emulator)

Issue still exist
flutter doctor -v
[✓] Flutter (Channel dev, v1.16.4-pre.50, on Mac OS X 10.15.4 19E266, locale
    en-GB)
    • Flutter version 1.16.4-pre.50 at /Users/taha/Code/flutter_dev
    • Framework revision d14a301e41 (3 days ago), 2020-03-31 19:14:22 -0400
    • Engine revision 8166a91bca
    • Dart version 2.8.0 (build 2.8.0-dev.19.0 fae35fca47)

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at /Users/taha/Code/sdk
    • Platform android-29, build-tools 29.0.3
    • ANDROID_HOME = /Users/taha/Code/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      1.8.0_212-release-1586-b4-5784211)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.4)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.4, Build version 11E146
    • CocoaPods version 1.9.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 3.6)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 44.0.2
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build
      1.8.0_212-release-1586-b4-5784211)

[✓] VS Code (version 1.43.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.8.1

[✓] Connected device (4 available)
    • SM M305F   • 32003c30dc19668f • android-arm64  • Android 10 (API 29)
    • macOS      • macOS            • darwin-x64     • Mac OS X 10.15.4 19E266
    • Chrome     • chrome           • web-javascript • Google Chrome
      80.0.3987.149
    • Web Server • web-server       • web-javascript • Flutter Tools

• No issues found!

I can reproduce without using a third-party package
Steps to reproduce

Run the code sample below

code sample
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      theme: ThemeData.dark(),
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String helloMessage = 'Hello World';
  bool _keyboardOn = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('_keyboardOn $_keyboardOn'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _keyboardOn
                ? Container()
                : Spacer(
                    flex: 2,
                  ),
            TextField(
              controller: TextEditingController(),
            ),
            Spacer(),
            _keyboardOn
                ? Container()
                : Text('keyboard is off'), //comment this line to make it work
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton.extended(
        label: Text('Tap here'),
        icon: Icon(Icons.touch_app),
        onPressed: () {
          setState(() {
            _keyboardOn = !_keyboardOn;
          });
        },
      ),
    );
  }
}

Tap on TextField, bring up the keyboard then Tap FAB

Result:
Keyboard closes when tapping on FAB

multiple flutter doctor -v
[✓] Flutter (Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-x64, locale
    en-GB)
    • Flutter version 1.22.5 at /Users/tahatesser/Code/flutter_stable
    • Framework revision 7891006299 (7 days ago), 2020-12-10 11:54:40 -0800
    • Engine revision ae90085a84
    • Dart version 2.10.4

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/tahatesser/Code/sdk
    • Platform android-30, build-tools 30.0.2
    • ANDROID_HOME = /Users/tahatesser/Code/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    • CocoaPods version 1.10.0

[!] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    ✗ Flutter plugin not installed; this adds Flutter specific functionality.
    ✗ Dart plugin not installed; this adds Dart specific functionality.
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6915495)

[✓] VS Code (version 1.52.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.17.0

[✓] Connected device (1 available)
    • iPhone 12 (mobile) • 01685E98-F396-4EB9-9C58-8B92677E24D5 • ios •
      com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)

! Doctor found issues in 1 category.

[✓] Flutter (Channel master, 1.26.0-2.0.pre.64, on macOS 11.1 20C69 darwin-x64,
    locale en-GB)
    • Flutter version 1.26.0-2.0.pre.64 at /Users/tahatesser/Code/flutter_master
    • Framework revision 9ff4326e1f (5 hours ago), 2020-12-17 06:19:05 +0000
    • Engine revision 6edb402ee4
    • Dart version 2.12.0 (build 2.12.0-157.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at /Users/tahatesser/Code/sdk
    • Platform android-30, build-tools 30.0.2
    • ANDROID_HOME = /Users/tahatesser/Code/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6915495)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.3)
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.3, Build version 12C33
    • CocoaPods version 1.10.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6915495)

[!] Android Studio
    • Android Studio at /Applications/Android/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Android Studio not found at /Applications/Android/Contents
    • Try updating or re-installing Android Studio.

[✓] VS Code (version 1.52.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.17.0

[✓] Connected device (3 available)
    • iPhone 12 (mobile) • 01685E98-F396-4EB9-9C58-8B92677E24D5 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)
    • macOS (desktop)    • macos                                • darwin-x64
      • macOS 11.1 20C69 darwin-x64
    • Chrome (web)       • chrome                               • web-javascript
      • Google Chrome 87.0.4280.88

! Doctor found issues in 1 category.

I verified the issue on the latest stable and the master channel and I can still reproduce the same behavior with the above reproducible steps the keyboard closes when the widget tree is modified.

code sample
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      theme: ThemeData.dark(),
      home: Home(),
    );
  }
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String helloMessage = 'Hello World';
  bool _keyboardOn = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('_keyboardOn $_keyboardOn'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _keyboardOn
                ? Container()
                : Spacer(
                    flex: 2,
                  ),
            TextField(
              controller: TextEditingController(),
            ),
            Spacer(),
            _keyboardOn
                ? Container()
                : Text('keyboard is off'), //comment this line to make it work
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton.extended(
        label: Text('Tap here'),
        icon: Icon(Icons.touch_app),
        onPressed: () {
          setState(() {
            _keyboardOn = !_keyboardOn;
          });
        },
      ),
    );
  }
}

flutter doctor -v (mac)
[✓] Flutter (Channel master, 3.6.0-6.0.pre.33, on macOS 12.6 21G115 darwin-arm64,
    locale en-IN)
    • Flutter version 3.6.0-6.0.pre.33 on channel master at
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision a9858ec524 (72 minutes ago), 2022-11-21 10:58:11 -0500
    • Engine revision 46a6b54295
    • Dart version 2.19.0 (build 2.19.0-406.0.dev)
    • DevTools version 2.19.0
    • If those were intentional, you can disregard the above warnings; however it is
      recommended to use "git" directly to perform update checks and upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc4)
    • Android SDK at /Users/mahesh/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0-rc4
    • ANDROID_HOME = /Users/mahesh/Library/Android/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14A400
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)

[✓] IntelliJ IDEA Community Edition (version 2021.2.1)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 61.2.4
    • Dart plugin version 212.5080.8

[✓] VS Code (version 1.70.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.53.20221101

[✓] Connected device (3 available)
    • iPhone 12 Pro (mobile) • 026D5789-9E78-4AD5-B1B2-3F8D4E7F65E4 • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
    • macOS (desktop)        • macos                                • darwin-arm64
      • macOS 12.6 21G115 darwin-arm64
    • Chrome (web)           • chrome                               • web-javascript
      • Google Chrome 107.0.5304.110

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

[✓] Flutter (Channel stable, 3.3.9, on macOS 12.6 21G115 darwin-arm, locale en-IN)
    • Flutter version 3.3.9 on channel stable at /Users/mahesh/Development/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision b8f7f1f986 (24 hours ago), 2022-11-23 06:43:51 +0900
    • Engine revision 8f2221fbef
    • Dart version 2.18.5
    • DevTools version 2.15.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc4)
    • Android SDK at /Users/mahesh/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0-rc4
    • ANDROID_HOME = /Users/mahesh/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.0.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14A400
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)

[✓] IntelliJ IDEA Community Edition (version 2021.2.1)
    • IntelliJ at /Applications/IntelliJ IDEA CE.app
    • Flutter plugin version 61.2.4
    • Dart plugin version 212.5080.8

[✓] VS Code (version 1.70.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.53.20221101

[✓] Connected device (3 available)
    • iPhone 12 Pro (mobile) • 026D5789-9E78-4AD5-B1B2-3F8D4E7F65E4 • ios            •
      com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
    • macOS (desktop)        • macos                                • darwin-arm64   • macOS 12.6 21G115 darwin-arm
    • Chrome (web)           • chrome                               • web-javascript • Google Chrome 107.0.5304.110

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!

authors: TahaTesser maheshmnj matejwamf