text:
App bar and tab bar, where the app bar hides when you scroll up

This is the desired behaviour (video from Tabs - Material.io). This works in the same way as the Android WhatsApp application. When you scroll down, the app bar gets hidden, while the tab bar always stays in view. When you scroll back up, the app bar shows again smoothly.
This is the code to recreate. (See GIF here for a demonstration of the problem)
Here is the basic structure:

MaterialApp

DefaultTabController

Scaffold

NestedScrollView

headerSliverBuilder: SliverAppBar

bottom: TabBar

body: TabBarView

Problems/issues

snap: true is necessary, although I do not want a snapping behaviour
Content gets hidden when you change tabs – This can probably be solved using the SafeArea widget. (See GIF here)

I also have also tried switching to a Stateful widget for controlling tabs, but that did not make any difference. I do not think it should make a difference.
Related stackoverflow question
https://stackoverflow.com/questions/55187332/flutter-tabbar-and-sliverappbar-that-hides-when-you-scroll-down
The answer does not solve the problem completely.
Possible related issues

https://github.com/flutter/flutter/issues/17518
https://github.com/flutter/flutter/issues/22475

Hi, you need to use SliverOverlapAbsorber/SliverOverlapInjector, the following code works for me:
@override
  Widget build(BuildContext context) {
    return Material(
      child: Scaffold(
        body: DefaultTabController(
          length: _tabs.length, // This is the number of tabs.
          child: NestedScrollView(
            headerSliverBuilder:
                (BuildContext context, bool innerBoxIsScrolled) {
              // These are the slivers that show up in the "outer" scroll view.
              return <Widget>[
                SliverOverlapAbsorber(
                  // This widget takes the overlapping behavior of the SliverAppBar,
                  // and redirects it to the SliverOverlapInjector below. If it is
                  // missing, then it is possible for the nested "inner" scroll view
                  // below to end up under the SliverAppBar even when the inner
                  // scroll view thinks it has not been scrolled.
                  // This is not necessary if the "headerSliverBuilder" only builds
                  // widgets that do not overlap the next sliver.
                  handle:
                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                  child: SliverSafeArea(
                    top: false,
                    sliver: SliverAppBar(
                      title: const Text('Books'),
                      floating: true,
                      pinned: true,
                      snap: false,
                      primary: true,
                      forceElevated: innerBoxIsScrolled,
                      bottom: TabBar(
                        // These are the widgets to put in each tab in the tab bar.
                        tabs: _tabs.map((String name) => Tab(text: name)).toList(),
                      ),
                    ),
                  ),
                ),
              ];
            },
            body: TabBarView(
              // These are the contents of the tab views, below the tabs.
              children: _tabs.map((String name) {
                return SafeArea(
                  top: false,
                  bottom: false,
                  child: Builder(
                    // This Builder is needed to provide a BuildContext that is "inside"
                    // the NestedScrollView, so that sliverOverlapAbsorberHandleFor() can
                    // find the NestedScrollView.
                    builder: (BuildContext context) {
                      return CustomScrollView(
                        // The "controller" and "primary" members should be left
                        // unset, so that the NestedScrollView can control this
                        // inner scroll view.
                        // If the "controller" property is set, then this scroll
                        // view will not be associated with the NestedScrollView.
                        // The PageStorageKey should be unique to this ScrollView;
                        // it allows the list to remember its scroll position when
                        // the tab view is not on the screen.
                        key: PageStorageKey<String>(name),
                        slivers: <Widget>[
                          SliverOverlapInjector(
                            // This is the flip side of the SliverOverlapAbsorber above.
                            handle:
                                NestedScrollView.sliverOverlapAbsorberHandleFor(
                                    context),
                          ),
                          SliverPadding(
                            padding: const EdgeInsets.all(8.0),
                            // In this example, the inner scroll view has
                            // fixed-height list items, hence the use of
                            // SliverFixedExtentList. However, one could use any
                            // sliver widget here, e.g. SliverList or SliverGrid.
                            sliver: SliverFixedExtentList(
                              // The items in this example are fixed to 48 pixels
                              // high. This matches the Material Design spec for
                              // ListTile widgets.
                              itemExtent: 60.0,
                              delegate: SliverChildBuilderDelegate(
                                (BuildContext context, int index) {
                                  // This builder is called for each child.
                                  // In this example, we just number each list item.
                                  return Container(
                                      color: Color((math.Random().nextDouble() *
                                                      0xFFFFFF)
                                                  .toInt() <<
                                              0)
                                          .withOpacity(1.0));
                                },
                                // The childCount of the SliverChildBuilderDelegate
                                // specifies how many children this inner list
                                // has. In this example, each tab has a list of
                                // exactly 30 items, but this is arbitrary.
                                childCount: 30,
                              ),
                            ),
                          ),
                        ],
                      );
                    },
                  ),
                );
              }).toList(),
            ),
          ),
        ),
      ),
    );
  }

@iRbouh
Thank you for your answer. This seems to be the closest the solve the problem, but the problem is still that snap: true is required for the app bar to show up when you scroll from any position on the screen, unfortunately

@themindstorm
Glad you found an answer! Also, if you change snap = true then it works but it is slightly delayed.

How exactly is it working for you? For me, snap: true is required

@iRbouh
Sorry to disturb you, but is there anything that can be done to remove this white space above the list? I believe it is being created by the sliverOverlapAbsorberHandleFor.

@themindstorm
It's being caused by the SliverPadding widget

@cholojuanito
Thanks! BTW, I tested the app on a physical Android device, and the space above the list (as seen in the image of my previous post) is not there. Not that I'm complaining.
So the problem seems to be because of the iPhone notch

@themindstorm
Okay, so it changes between devices then it's probably the SafeArea widget. I think if you move it around (higher or lower in the widget tree) you'll be able to find the right setup for all devices

@cholojuanito
Okay, thank you for your help

There was also one more issue (on iPhone X only):
The last few containers will never come into view (not sure why). This can be fixed by wrapping the SliverFixedExtentList with
SliverPadding(
    padding: EdgeInsets.only(bottom: 200),  // <-- change to 150 maybe
    sliver: ...
)

And for the iPhone X safe area issue, I just added these lines to the NestedScrollView.sliverOverlapAbsorberHandleFor():
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
child: SliverSafeArea(
    top: false,
    bottom: false,
    sliver: SliverAppBar(
        ...
    )
    ...
)

I haven't tested this on any rectangular-shaped phone yet.

Do we know if the 'snap' feature will be fixed so it scrolls back (down) on scroll up, and doesn't wait for it to stop first? (IE - in the Android Play Music app).

@Dacarnix
Sorry, but I have no idea. I've asked the same question on reddit and stackoverflow, but I didn't get any 100% working answers:

https://stackoverflow.com/questions/55187332/flutter-tabbar-and-sliverappbar-that-hides-when-you-scroll-down
https://www.reddit.com/r/FlutterDev/comments/b23sc9/is_this_tab_behaviour_possible_in_flutter_taken/
https://www.reddit.com/r/Flutter/comments/b2jroh/how_do_you_make_this_sliverappbartabbar_layout/

There are also a few other issues to follow:

#17518
#22475

The problem is because at this line (and any other that reads the scrolloffset from constraints) the offstet returned is only the one relative to the "headerSliverBuilder" portion and not the "body" portion.
I don't know how to inject the correct value there but it seems that it would be the fix.
Also, when using a ScrollController on a NestedScrollView what you get when acessing position is also only the header scroll, not the header+body scroll.
I don't know how but they should be receiving the correct values...

Hi, you need to use SliverOverlapAbsorber/SliverOverlapInjector, the following code works for me (Gist) :
@override
  Widget build(BuildContext context) {
    return Material(
      child: Scaffold(
        body: DefaultTabController(
          length: _tabs.length, // This is the number of tabs.
          child: NestedScrollView(
            headerSliverBuilder:
                (BuildContext context, bool innerBoxIsScrolled) {
              // These are the slivers that show up in the "outer" scroll view.
              return <Widget>[
                SliverOverlapAbsorber(
                  // This widget takes the overlapping behavior of the SliverAppBar,
                  // and redirects it to the SliverOverlapInjector below. If it is
                  // missing, then it is possible for the nested "inner" scroll view
                  // below to end up under the SliverAppBar even when the inner
                  // scroll view thinks it has not been scrolled.
                  // This is not necessary if the "headerSliverBuilder" only builds
                  // widgets that do not overlap the next sliver.
                  handle:
                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                  child: SliverSafeArea(
                    top: false,
                    sliver: SliverAppBar(
                      title: const Text('Books'),
                      floating: true,
                      pinned: true,
                      snap: false,
                      primary: true,
                      forceElevated: innerBoxIsScrolled,
                      bottom: TabBar(
                        // These are the widgets to put in each tab in the tab bar.
                        tabs: _tabs.map((String name) => Tab(text: name)).toList(),
                      ),
                    ),
                  ),
                ),
              ];
            },
            body: TabBarView(
              // These are the contents of the tab views, below the tabs.
              children: _tabs.map((String name) {
                return SafeArea(
                  top: false,
                  bottom: false,
                  child: Builder(
                    // This Builder is needed to provide a BuildContext that is "inside"
                    // the NestedScrollView, so that sliverOverlapAbsorberHandleFor() can
                    // find the NestedScrollView.
                    builder: (BuildContext context) {
                      return CustomScrollView(
                        // The "controller" and "primary" members should be left
                        // unset, so that the NestedScrollView can control this
                        // inner scroll view.
                        // If the "controller" property is set, then this scroll
                        // view will not be associated with the NestedScrollView.
                        // The PageStorageKey should be unique to this ScrollView;
                        // it allows the list to remember its scroll position when
                        // the tab view is not on the screen.
                        key: PageStorageKey<String>(name),
                        slivers: <Widget>[
                          SliverOverlapInjector(
                            // This is the flip side of the SliverOverlapAbsorber above.
                            handle:
                                NestedScrollView.sliverOverlapAbsorberHandleFor(
                                    context),
                          ),
                          SliverPadding(
                            padding: const EdgeInsets.all(8.0),
                            // In this example, the inner scroll view has
                            // fixed-height list items, hence the use of
                            // SliverFixedExtentList. However, one could use any
                            // sliver widget here, e.g. SliverList or SliverGrid.
                            sliver: SliverFixedExtentList(
                              // The items in this example are fixed to 48 pixels
                              // high. This matches the Material Design spec for
                              // ListTile widgets.
                              itemExtent: 60.0,
                              delegate: SliverChildBuilderDelegate(
                                (BuildContext context, int index) {
                                  // This builder is called for each child.
                                  // In this example, we just number each list item.
                                  return Container(
                                      color: Color((math.Random().nextDouble() *
                                                      0xFFFFFF)
                                                  .toInt() <<
                                              0)
                                          .withOpacity(1.0));
                                },
                                // The childCount of the SliverChildBuilderDelegate
                                // specifies how many children this inner list
                                // has. In this example, each tab has a list of
                                // exactly 30 items, but this is arbitrary.
                                childCount: 30,
                              ),
                            ),
                          ),
                        ],
                      );
                    },
                  ),
                );
              }).toList(),
            ),
          ),
        ),
      ),
    );
  }

when changing tab after scrolling on another tab, the scroll position will follow, how would you fix that?

@azuddin
Are you facing the problem shown in this GIF?

@azuddin
Are you facing the problem shown in this GIF?

sort of. my behaviour more like this

here's the code:
import 'package:flutter/material.dart';
import 'dart:math';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: NewsScreen(),
    );
  }
}

class NewsScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _NewsScreenState();
}

class _NewsScreenState extends State<NewsScreen> {
  final List<String> listItems = [];

  final List<String> _tabs = <String>[
    "Featured",
    "Popular",
    "Latest",
  ];

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Scaffold(
        body: DefaultTabController(
          length: _tabs.length, // This is the number of tabs.
          child: NestedScrollView(
            headerSliverBuilder:
                (BuildContext context, bool innerBoxIsScrolled) {
              // These are the slivers that show up in the "outer" scroll view.
              return <Widget>[
                SliverOverlapAbsorber(
                  // This widget takes the overlapping behavior of the SliverAppBar,
                  // and redirects it to the SliverOverlapInjector below. If it is
                  // missing, then it is possible for the nested "inner" scroll view
                  // below to end up under the SliverAppBar even when the inner
                  // scroll view thinks it has not been scrolled.
                  // This is not necessary if the "headerSliverBuilder" only builds
                  // widgets that do not overlap the next sliver.
                  handle:
                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                  child: SliverSafeArea(
                    top: false,
                    sliver: SliverAppBar(
                      title: const Text('Books'),
                      floating: true,
                      pinned: true,
                      snap: true,
                      primary: true,
                      forceElevated: innerBoxIsScrolled,
                      bottom: TabBar(
                        // These are the widgets to put in each tab in the tab bar.
                        tabs: _tabs
                            .map((String name) => Tab(text: name))
                            .toList(),
                      ),
                    ),
                  ),
                ),
              ];
            },
            body: TabBarView(
              // These are the contents of the tab views, below the tabs.
              children: _tabs.map((String name) {
                return SafeArea(
                  top: false,
                  bottom: false,
                  child: Builder(
                    // This Builder is needed to provide a BuildContext that is "inside"
                    // the NestedScrollView, so that sliverOverlapAbsorberHandleFor() can
                    // find the NestedScrollView.
                    builder: (BuildContext context) {
                      return CustomScrollView(
                        // The "controller" and "primary" members should be left
                        // unset, so that the NestedScrollView can control this
                        // inner scroll view.
                        // If the "controller" property is set, then this scroll
                        // view will not be associated with the NestedScrollView.
                        // The PageStorageKey should be unique to this ScrollView;
                        // it allows the list to remember its scroll position when
                        // the tab view is not on the screen.
                        key: PageStorageKey<String>(name),
                        slivers: <Widget>[
                          SliverOverlapInjector(
                            // This is the flip side of the SliverOverlapAbsorber above.
                            handle:
                                NestedScrollView.sliverOverlapAbsorberHandleFor(
                                    context),
                          ),
                          SliverPadding(
                            padding: const EdgeInsets.all(8.0),
                            // In this example, the inner scroll view has
                            // fixed-height list items, hence the use of
                            // SliverFixedExtentList. However, one could use any
                            // sliver widget here, e.g. SliverList or SliverGrid.
                            sliver: SliverFixedExtentList(
                              // The items in this example are fixed to 48 pixels
                              // high. This matches the Material Design spec for
                              // ListTile widgets.
                              itemExtent: 100.0,
                              delegate: SliverChildBuilderDelegate(
                                (BuildContext context, int index) {
                                  // This builder is called for each child.
                                  // In this example, we just number each list item.
                                  return Column(
                                    children: <Widget>[
                                      Container(
                                        height: 90,
                                        width: double.infinity,
                                        color: Colors.blueGrey,
                                        child: Column(
                                          mainAxisAlignment:
                                              MainAxisAlignment.center,
                                          children: <Widget>[
                                            Text('$index'),
                                          ],
                                        ),
                                      ),
                                      SizedBox(height: 10),
                                    ],
                                  );
                                },
                                // The childCount of the SliverChildBuilderDelegate
                                // specifies how many children this inner list
                                // has. In this example, each tab has a list of
                                // exactly 30 items, but this is arbitrary.
                                childCount: 30,
                              ),
                            ),
                          ),
                        ],
                      );
                    },
                  ),
                );
              }).toList(),
            ),
          ),
        ),
      ),
    );
  }
}

@azuddin
The white space at the top is likely being caused by a SafeArea along with the iPhone X notch (if I'm not mistaken). I managed to fix this in my app.
Take a look at this file: https://github.com/holt-soundboard/holt-soundboard-mobile/blob/master/lib/pages/home_page.dart#L28
Scaffold(
  drawer: AppDrawer(),
  body: DefaultTabController(
    length: soundsProvider.getCharacters().length,
    child: NestedScrollView(
      headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
        return <Widget>[
          SliverOverlapAbsorber(
            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
            child: SliverSafeArea(
              top: false,
              bottom: false,
              sliver: Appbars.primary(context) // <-- This is just a sliver app bar which is pinned and floating
            ),
          )
        ];
      },
      body: TabBarView(
        children: <Widget>[
          for (var character in soundsProvider.getCharacters())
            SafeArea(
              top: false,
              bottom: false,
              child: Builder(
                builder: (BuildContext context) {
                  return CustomScrollView(
                    key: PageStorageKey<String>(character),
                    slivers: <Widget>[
                      SliverOverlapInjector(
                        handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                      ),
                      SliverPadding(
                        padding: EdgeInsets.all(PaddingValues.main),
                        sliver: SoundsGrid(
                          character: character,
                          isFavoritesGrid: false
                        )
                      ),
                      SliverToBoxAdapter(
                        child: Footer(),
                      )
                    ],
                  );
                }
              ),
            )
        ],
      )
    ),
  )
);

I'm using a sliver grid, not a list, but I think they work similarly.
Try using this code and see if it works. It's working fine for me on all devices.

@themindstorm yup it fix the extra space problem. but the scroll problem still presents. I've created an issue for this https://github.com/flutter/flutter/issues/40740

Any updates on the original issue here?

return DefaultTabController(
      length: 3,
      child: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerboxisScrolled) {
          return <Widget>[
            SliverAppBar(
              expandedHeight: 205,
              floating: false,
              pinned: false,
              automaticallyImplyLeading: false,
              backgroundColor: Theme.of(context).primaryColor,
              flexibleSpace: FlexibleSpaceBar(background: _profilebg()),
            ),
            SliverPersistentHeader(
              delegate: _SliverAppBarDelegate(
                  TabBar(
                    labelColor: Theme.of(context).accentColor,
                    labelStyle: TextStyle(fontWeight: FontWeight.bold),
                    unselectedLabelStyle:
                        TextStyle(fontWeight: FontWeight.normal),
                    indicatorColor: Theme.of(context).accentColor,
                    unselectedLabelColor: Colors.grey,
                    tabs: <Widget>[
                      Tab(
                        child: Center(
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[Text('145'), Text('Photos')],
                          ),
                        ),
                      ),
                      Tab(
                        child: Center(
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[Text('754'), Text('Following')],
                          ),
                        ),
                      ),
                      Tab(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[Text('56'), Text('Followers')],
                        ),
                      ),
                    ],
                  ),
                  Theme.of(context).primaryColor),
              pinned: true,
              floating: true,
            )
          ];
        },
        body: TabBarView(controller: tabController,
            children: <Widget>[
              UserPhotos(),
              Following(),
              Followers(),
            ]),
      ),
    );

i have same issue. In tabbarview i get some datas from an api with FutureBuilder but my slivers do not work. Any suggestion? Thanks.

If anyone wants to refer a working code sample for whatsapp type floating sliverappbar with tabs, here it is -> https://dartpad.dev/0955dcf876ba24619b86d49ec50788cc?

If anyone wants to refer a working code sample for whatsapp type floating sliverappbar with tabs, here it is -> https://dartpad.dev/0955dcf876ba24619b86d49ec50788cc?

Your solution doesnot solve :

Content gets hidden when you change tabs – This can probably be solved using the SafeArea widget. (See GIF here)

Keep the Text at top instead at center and you will see the issue

I tried to address all the points in this stackoverflow answer. Thanks to beautiful Flutter docs for NestedScrollView

@kmanadkat Tried your dart pad example.
Getting this error https://stackoverflow.com/questions/58339739/nestedscrollview-issue-throwing-error-when-switching-between-two-screens . Do you have any idea about this? Thanks .

@kmanadkat Tried your dart pad example.
Getting this error https://stackoverflow.com/questions/58339739/nestedscrollview-issue-throwing-error-when-switching-between-two-screens . Do you have any idea about this? Thanks .

I rechecked the dartpad code, seems it is still working. Have you tried any of the solutions mentioned in stackoverflow link you shared?
I have not encountered this error before. Perhaps, data to be populated in list is empty maybe that is why you are seeing that error. Preload the data before somewhere in Model and then load the widget with data from Model.

Solved the issue with the help of this code
body: TabBarView(controller: _tabController, children: [
CustomScrollView(
controller: _scrollController,
slivers: [SliverToBoxAdapter(child: Container())],
),
CustomScrollView(
controller: _scrollController,
slivers: [SliverToBoxAdapter(child: Container())],
),
CustomScrollView(
controller: _scrollController,
slivers: [SliverToBoxAdapter(child: Container())],
),
]),
      Referred from link https://github.com/flutter/flutter/issues/51205

      Now how to hide the silver app bar title?  Do you have any idea about this? Thanks.

authors: AlptugYaman CountPablo Dacarnix azuddin cholojuanito iRbouh kaxp kmanadkat lucasavila00 ninest rashmisridar themindstorm


text:
I cannot render the ListView with my items from StreamBuilder

class _TagsState extends State<TagsPage> {

  final TagRepository _tagRepository;
  final TagsBloc bloc;

  @override
  Widget build(BuildContext context) => Scaffold(
        body: Center(
          child: StreamBuilder<List<Tag>>(
            stream: bloc.tags,
            builder: (context, snapshot) {
              if (snapshot.data == null || snapshot.data.isEmpty) {
                print("[TagsPage] build - snapshot.data is null");
              } else {
                print("[TagsPage] build - snapshot.data.length: ${snapshot.data.length}");
                return ListView(
                  children: snapshot.data.map(_buildItem).toList(),
                );
              }
            },
          ),
        ),
      );

  _buildItem(Tag tag) => Text(tag.name);

}

snapshot.data is not null and not empty.
It has data, but it doesn't render to Text widget.
log is here:
I/flutter (21410): [TagsPage][JOS] build - snapshot.data.length: 1
I/flutter (21410): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (21410): The following assertion was thrown building StreamBuilder<List>(dirty, dependencies:
I/flutter (21410): [_LocalizationsScope-[GlobalKey#cebbd], _InheritedTheme], state: _StreamBuilderBaseState<List,
I/flutter (21410): AsyncSnapshot<List>>#1b6a7):
I/flutter (21410): type 'List' is not a subtype of type 'List'
I/flutter (21410): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (21410): more information in this error message to help you determine and fix the underlying cause.
I/flutter (21410): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (21410):   https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (21410): When the exception was thrown, this was the stack:
I/flutter (21410): #0      _TagsState.build. (package:jos/pages/tags.dart:54:59)

What's the type of bloc.tags?  It looks like there's some type mismatch going on, you very likely need some kind of .cast.
This would probably be a good stackoverflow question, or a quetion on one of the other channels at https://flutter.dev/community.  It's not really a bug in the framework (despite what the assertion error says).

source: gharchive/issue

repo: flutter/flutter

license_type: permissive

license_source: github-api


text:
Enable Web unit tests

Web unit tests are currently disabled on Cirrus due to flakiness. We should fix the flakiness and re-enable them.
One possible solution is to shard tests and create a new instance of Chrome per shard. Currently all 4700+ run on the same Chrome instance. It is possible that Chrome can't handle that much load.

Marking this as done. We can run tests now, and some already run on Cirrus as part of the normal workflow. From now on, we just need to incrementally add as many tests as possible.


text:
flutter test should only build tests that were asked to run

Use case
flutter test --platform=chrome test/foo_test.dart should be fast. Instead, as of right now it will first build every single *_test.dart file before running the test. For a project with a large number of tests (e.g. package:flutter) this can take a long time (e.g. on my dual Xeon workstation with 128GB RAM it takes 2.5 minutes before the test starts running).
Proposal
Make the build smarter. Teach it to scope the build to only tests that were requested.
/cc @jakemac53 @jonahwilliams

Originally I had it this way by piping through a list of targets to build. It was pointed out to me that you can't have multiple build daemons running with different configurations. This means that trying to build and run a single test while you are running your web application won't work.

So is the fix somewhere in dart_lang/build?

cc @vsmenon for prioritization
Adding full featured functionality for this would be a lot of work, but it would benefit all users. Especially for release mode tests having to compile all apps just to run a single one is a major pain.
Specifically for good support one thing we would need is the ability to know what other files a test depends on outside of just the compiled javascript so we ensure that gets built too. That almost certainly has to involve configuration, but it could be optional and only required for tests that rely on other generated artifacts.

It would also be possible to add a feature such as build all the transitive primary outputs of this input file which might work well enough for the flutter case, and a lot of other cases. You could just provide the test file and then it would build everything required for a basic test.

I don't know how import --platform=chrome actually is. It would certainly make Yegor's debugging easier but I don't think we expect people outside of the flutter web team to use it

@jonahwilliams It also affects the speed of our CI tests. We won't be able to shard our tests effectively if every shard builds all the tests.
/cc @ferhatb to comment on whether we aim flutter test --platform=chrome to be a developer-facing tool. If so, then this is much more critical, as 2.5 minutes for a single tests would be unacceptable.

Added dependency: dart as it seems that the fix is in https://github.com/dart-lang/build

@jonahwilliams It also affects the speed of our CI tests. We won't be able to shard our tests effectively if every shard builds all the tests.

As far as CI specifically goes - its actually much more efficient in general to build all tests in a single step, then use that build output to run each test shard. That way all the shards share compilation of any shared libraries, and don't do any duplicate work.

/cc @ferhatb to comment on whether we aim flutter test --platform=chrome to be a developer-facing tool. If so, then this is much more critical, as 2.5 minutes for a single tests would be unacceptable.

While initial builds do matter, our position is that incremental builds are a lot more important. How long does it take to do a new build after making an edit to something in flutter?
The main reason that we haven't tackled this feature previously is that the individual tests themselves compile quite quickly, so its only when you have a large number of them that it really starts to matter. The complexity added on both the build system and users hasn't been worth it (yet).

its actually much more efficient in general to build all tests in a single step, and then use that build output to run each test shard. That way all the shards share compilation of any shared libraries, and don't do any duplicate work.

I don't believe we have access to CI infrastructure capable of sharing build artifacts. Also, I'm very skeptical that building thousands of tests in a bottleneck is faster. It didn't take long to feel the pain from it already.

While initial builds do matter, our position is that incremental builds are a lot more important. How long does it take to do a new build after making an edit to something in flutter?

Without editing the framework:
$ time flutter test --platform=chrome test/foundation/assertions_test.dart
00:02 +7: All tests passed!

real	0m8.669s
user	0m8.061s
sys	0m2.158s

After editing the framework:
$ time flutter test --platform=chrome test/foundation/assertions_test.dart
00:02 +7: All tests passed!

real	2m34.243s
user	0m42.012s
sys	0m9.525s

So 8.6 seconds vs 2.5 minutes. Looking at --verbose output I see this line:
9.9s elapsed, 76/87 actions completed.

Followed by a long tail of lines like this:
building for target test/widgets/parent_data_test.dart.browser_test.dart

So the vast majority of time is spent on recompiling all tests when all I want to do is run one test.

The main reason that we haven't tackled this feature previously is that the individual tests themselves compile quite quickly, so its only when you have a large number of them that it really starts to matter. The complexity added on both the build system and users hasn't been worth it (yet).

I think we're finding out that this approach doesn't scale. This is going to be a big pain point for the team very shortly, and possibly for users, particularly for big customers.

I think I should add the test filtering back to unblock your local development. We can deal with changes to package:build and the web testing story afterwards

I think the fix here is to do one of the simple but not really complete options I outlined above. I think probably the best option is allowing you to specify an exact output to build. This would be a pretty simple change and would be good enough for flutter since the hardcoded build script means you can't have any other generated files the test is relying on anyways.

I think I should add the test filtering back to unblock your local development. We can deal with changes to package:build and the web testing story afterwards

Be careful how this is done - I can't remember the details of how it worked before but I don't know of any way to do it that won't cause issues of some sort given the features available today. Feel free to cc me on any prs here.

I don't believe we have access to CI infrastructure capable of sharing build artifacts.

CI limitations here are unfortunate, I don't think there is anything our team can really do about that. This seems like it would benefit all flutter tests not just web tests and is a more systematic issue.

Also, I'm very skeptical that building thousands of tests in a bottleneck is faster. It didn't take long to feel the pain from it already.

The pain you feel is when trying to run a single test locally, which is legitimate for projects of this size.
From a CI perspective based on the results above I think it shows that it would be a net benefit today to build them all in a single build (rebuilding all the tests took significantly less than half the time of the initial build, so building all deps was the majority of the time not building the tests).

I think we're finding out that this approach doesn't scale. This is going to be a big pain point for the team very shortly, and possibly for users, particularly for big customers.

Yes, the system was explicitly never designed to scale well for running single tests in a package of this size. It is built on an assumption that packages are generally <=medium-large in size. We have had a small number of larger external users run into it though, so fixing this would help them too.
There isn't anything blocking supporting this use case other than sufficient motivation/prioritization to actually solve the problem. But as I mentioned i think we can half solve it in a way that works for flutter and lots of other people, so that is likely worth doing.

As an extra data point the same one test that takes 2.5 minutes on my workstation, takes >9 minutes on Cirrus CI to run.

The support is now added. @jonahwilliams please confirm that this issue is resolved.

authors: grouma jakemac53 jonahwilliams yjbanov


text:
Connecting IOS Phone in Windows for to IDE for HotReload - DART Socket ERROR

flutter_08.log
Anyone have a clue about this error ?

We do not support debugging iOS devices on windows

authors: badosanjos jonahwilliams


text:
[connectivity] Add Linux support

The API is currently pretty mobile-centric, so we'd need to evaluate whether we want to move toward a more generic API as part of adding desktop support.

Closing as connectivity is deprecated in favor of connectivity_plus.


text:
plugins Cirrus should ignore federated web plugins

They aren't building with stable yet. Once federated plugin support is available on stable, we can test on both branches.

This is fixed with my recent changes to plugin CI.

authors: collinjackson stuartmorgan


text:
[url_launcher] Android resumes with black screen

with statusBarBrightness
without statusBarBrightness

Steps to Reproduce
DEMO APPLICATION: https://gist.github.com/ianko/e5ab0da1c48736e65538305c8ded1a7d

Import the latest url_launcher version (5.2.3 as of today)
Launch a URL passing a statusBarBrightness
Hit the back button
Notice the screen went all black
If you repeat the steps but without passing a statusBarBrightness, it works fine.

Target Platform: ANDROID
Target OS version/browser: Any
Devices: Any
Logs

W/ActivityThread(27915): handleWindowVisibility: no activity for token android.os.BinderProxy@e077bb7

════════ Exception caught by scheduler library ═════════════════════════════════
The following assertion was thrown during a scheduler callback:
Failed assertion: boolean expression must not be null

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
  https://github.com/flutter/flutter/issues/new?template=BUG.md

When the exception was thrown, this was the stack
#0      RenderView.compositeFrame
#1      RendererBinding.drawFrame
#2      WidgetsBinding.drawFrame
#3      RendererBinding._handlePersistentFrameCallback
#4      SchedulerBinding._invokeFrameCallback
...
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════
Failed assertion: boolean expression must not be null
════════════════════════════════════════════════════════════════════════════════
D/        (27915): PlayerBase::PlayerBase()
D/        (27915): TrackPlayerBase::TrackPlayerBase()
I/libOpenSLES(27915): Emulating old channel mask behavior (ignoring positional mask 0x3, using default mask 0x3 based on channel count of 2)
I/cr_MediaCodecBridge(27915): create MediaCodec video decoder, mime video/avc
I/OMXClient(27915): IOmx service obtained
I/MediaCodec(27915): MediaCodec will operate in async mode
D/SurfaceUtils(27915): connecting to surface 0x76ac238010, reason connectToSurface
I/MediaCodec(27915): [OMX.qcom.video.decoder.avc] setting surface generation to 28584967
D/SurfaceUtils(27915): disconnecting from surface 0x76ac238010, reason connectToSurface(reconnect)
D/SurfaceUtils(27915): connecting to surface 0x76ac238010, reason connectToSurface(reconnect)
D/SurfaceUtils(27915): set up nativeWindow 0x76ac238010 for 1080x820, color 0x7fa30c06, rotation 0, usage 0x20002900
D/SurfaceUtils(27915): set up nativeWindow 0x76ac238010 for 1088x832, color 0x7fa30c06, rotation 0, usage 0x20002900
I/cr_MediaCodecBridge(27915): create MediaCodec video decoder, mime video/avc
I/OMXClient(27915): IOmx service obtained
I/MediaCodec(27915): MediaCodec will operate in async mode
D/SurfaceUtils(27915): connecting to surface 0x76ac239010, reason connectToSurface
I/MediaCodec(27915): [OMX.qcom.video.decoder.avc] setting surface generation to 28584968
D/SurfaceUtils(27915): disconnecting from surface 0x76ac239010, reason connectToSurface(reconnect)
D/SurfaceUtils(27915): connecting to surface 0x76ac239010, reason connectToSurface(reconnect)
D/SurfaceUtils(27915): set up nativeWindow 0x76ac239010 for 1080x820, color 0x7fa30c06, rotation 0, usage 0x20002900
D/SurfaceUtils(27915): set up nativeWindow 0x76ac239010 for 1088x832, color 0x7fa30c06, rotation 0, usage 0x20002900
I/cr_MediaCodecBridge(27915): create MediaCodec video decoder, mime video/avc
I/OMXClient(27915): IOmx service obtained
I/MediaCodec(27915): MediaCodec will operate in async mode
D/SurfaceUtils(27915): connecting to surface 0x77161a6010, reason connectToSurface
I/MediaCodec(27915): [OMX.qcom.video.decoder.avc] setting surface generation to 28584969
D/SurfaceUtils(27915): disconnecting from surface 0x77161a6010, reason connectToSurface(reconnect)
D/SurfaceUtils(27915): connecting to surface 0x77161a6010, reason connectToSurface(reconnect)
D/SurfaceUtils(27915): set up nativeWindow 0x77161a6010 for 1080x820, color 0x7fa30c06, rotation 0, usage 0x20002900
D/SurfaceUtils(27915): set up nativeWindow 0x77161a6010 for 1088x832, color 0x7fa30c06, rotation 0, usage 0x20002900
D/        (27915): PlayerBase::stop() from IPlayer
D/AudioTrack(27915): stop(34): called with 486266 frames delivered
W/cr_MediaCodecBridge(27915): Releasing: OMX.qcom.video.decoder.avc
D/SurfaceUtils(27915): disconnecting from surface 0x76ac238010, reason disconnectFromSurface
W/cr_MediaCodecBridge(27915): Codec released
W/cr_MediaCodecBridge(27915): Releasing: OMX.qcom.video.decoder.avc
D/SurfaceUtils(27915): disconnecting from surface 0x76ac239010, reason disconnectFromSurface
W/cr_MediaCodecBridge(27915): Codec released
W/cr_MediaCodecBridge(27915): Releasing: OMX.qcom.video.decoder.avc
D/SurfaceUtils(27915): disconnecting from surface 0x77161a6010, reason disconnectFromSurface
W/cr_MediaCodecBridge(27915): Codec released

Hi @ianko
can you please provide your flutter doctor -v
thank you"

@iapicca

CC @amirh as this seems to be related with the web view.

Removing "performance" label as this seems more of a rendering issue.

I have the same issue but my app returns to a while screen, probably because I don't use dark mode.
@ianko have you managed to get it fixed?

I found a solution here #29838

@daniil-shumko I did the same workaround.

If you repeat the steps but without passing a statusBarBrightness, it works fine.

authors: daniil-shumko ianko iapicca liyuqian


text:
Dismissible Widget confirm dismiss error if animation starts after the child has been scrolled

Steps to Reproduce
I have a list of widgets inside a CustomScroll, each widget is wrapped in a Dismissible widget and when someone dismiss the widget the confirmDismiss fires and a snackbar with an undo button is showed (like Keep Note app), Now if you scroll away from the widget and then click on undo an error is shown that the ticker animation has been disposed and is null, which makes sense the widget isn't there anymore, and if you don't push the undo button and let the snackbar dissapear it means the widget should start to resize (confirmDismiss returns true) and an error telling you the widget is not mounted. Shouldn't the dismissed widget check if it's mounted or not before starting a resize or _modecontroller.reverse animation? In that way it could fire the onDismissed callback without starting any animation.
The problem is there is no proper way to fire the onDismiss (so I can delete the object from the list) without starting the animation.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';

void main() => runApp(
    MaterialApp(
        home: Scaffold(
          body: CustomScrollView(
            cacheExtent: 50,
            slivers: <Widget>[
              Drag()
            ],
          ),
        )
    )
);

class Drag extends StatefulWidget {
  @override
  _DragState createState() => _DragState();
}

class _DragState extends State<Drag>{
  List<String> list = List<String>.from(
      'Lorem ipsum dolor sit '
          'amet, consectetur adipiscing elit, s'
          'ed do eiusmod tempor'.split('')
  );

  @override
  Widget build(BuildContext context) {
    return SliverList(
        delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index){
            return Dismissible(
              key: Key('$index${list[index]}'),
              background: Container(color: Colors.red,),
              confirmDismiss: (_) {
                Completer<bool> completer = Completer();
                final scaffold = Scaffold.of(context);
                scaffold.showSnackBar(
                    SnackBar(content: Text('Task dismissed'),
                      behavior: SnackBarBehavior.floating,
                      onVisible: () => Future.delayed(
                          const Duration(milliseconds: 4000), () {
                        if(completer.isCompleted) return;
                        completer.complete(true);
                      }
                      ),
                      action: SnackBarAction(
                          label: 'undo',
                          onPressed: () => completer.complete(false)
                      ),
                    )
                );
                return completer.future;
              },
              onDismissed: (_) => setState(() => list.removeAt(index)),
              child: Container(
                height: 100,
                width: double.infinity,
                color: index % 2 == 0 ? Colors.blue : Colors.green,
                child: Center(
                  child: Text(list[index], style: TextStyle(fontSize: 24),),
                ),
              ),
            );
          },
          childCount: list.isEmpty ? 0 : list.length,
        )
    );
  }
}

Logs
 [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: 'package:flutter/src/animation/animation_controller.dart': Failed assertion: line 484 pos 7: '_ticker != null': AnimationController.reverse() called
after AnimationController.dispose()
[   +2 ms] E/flutter ( 6276): AnimationController methods should not be used after calling dispose.
[   +1 ms] E/flutter ( 6276): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:42:39)
[   +1 ms] E/flutter ( 6276): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:38:5)
[        ] E/flutter ( 6276): #2      AnimationController.reverse (package:flutter/src/animation/animation_controller.dart:484:7)
[        ] E/flutter ( 6276): #3      _DismissibleState._handleDismissStatusChanged (package:flutter/src/widgets/dismissible.dart:449:25)
[        ] E/flutter ( 6276): <asynchronous suspension>
[        ] E/flutter ( 6276): #4      AnimationLocalStatusListenersMixin.notifyStatusListeners (package:flutter/src/animation/listener_helpers.dart:193:19)
[        ] E/flutter ( 6276): #5      AnimationController._checkStatusChanged (package:flutter/src/animation/animation_controller.dart:773:7)
[        ] E/flutter ( 6276): #6      AnimationController._tick (package:flutter/src/animation/animation_controller.dart:789:5)
[        ] E/flutter ( 6276): #7      Ticker._tick (package:flutter/src/scheduler/ticker.dart:237:5)
[        ] E/flutter ( 6276): #8      SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1102:15)
[        ] E/flutter ( 6276): #9      SchedulerBinding.handleBeginFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:1017:11)
[        ] E/flutter ( 6276): #10     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
[        ] E/flutter ( 6276): #11     SchedulerBinding.handleBeginFrame (package:flutter/src/scheduler/binding.dart:1015:17)
[        ] E/flutter ( 6276): #12     SchedulerBinding._handleBeginFrame (package:flutter/src/scheduler/binding.dart:949:5)
[        ] E/flutter ( 6276): #13     _rootRunUnary (dart:async/zone.dart:1138:13)
[        ] E/flutter ( 6276): #14     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
[        ] E/flutter ( 6276): #15     _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
[        ] E/flutter ( 6276): #16     _invoke1 (dart:ui/hooks.dart:273:10)
[        ] E/flutter ( 6276): #17     _beginFrame (dart:ui/hooks.dart:200:3)
[        ] E/flutter ( 6276):

[√] Flutter (Channel stable, v1.12.13+hotfix.9, on Microsoft Windows [VersiÃ³n 10.0.18363.720], locale es-MX)
    • Flutter version 1.12.13+hotfix.9 at E:\Programs\flutter
    • Framework revision f139b11009 (2 weeks ago), 2020-03-30 13:57:30 -0700
    • Engine revision af51afceb8
    • Dart version 2.7.2

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
    • Android SDK at C:\Users\dartz\AppData\Local\Android\Sdk
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.3
    • ANDROID_HOME = C:\Users\dartz\AppData\Local\Android\Sdk
    • Java binary at: E:\Programs\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)
    • All Android licenses accepted.

[√] Android Studio (version 3.6)
    • Android Studio at E:\Programs\Android\Android Studio
    • Flutter plugin version 44.0.2
    • Dart plugin version 192.7761
    • Java version OpenJDK Runtime Environment (build 1.8.0_212-release-1586-b04)

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

• No issues found!

Also I see this exception, when you dismissed and scrolled (without pressing undo).
It tries to delete, but element is already unmounted after scrolling
I/flutter (24587): ══╡ EXCEPTION CAUGHT BY ANIMATION LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (24587): The following NoSuchMethodError was thrown while notifying listeners for AnimationController:
I/flutter (24587): The method 'dependOnInheritedWidgetOfExactType' was called on null.
I/flutter (24587): Receiver: null
I/flutter (24587): Tried calling: dependOnInheritedWidgetOfExactType<Directionality>()
I/flutter (24587):
I/flutter (24587): When the exception was thrown, this was the stack:
I/flutter (24587): #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
I/flutter (24587): #1      Directionality.of (package:flutter/src/widgets/basic.dart:110:43)
I/flutter (24587): #2      _DismissibleState._extentToDirection (package:flutter/src/widgets/dismissible.dart:272:30)
I/flutter (24587): #3      _DismissibleState._dismissDirection (package:flutter/src/widgets/dismissible.dart:284:45)
I/flutter (24587): #4      _DismissibleState._handleResizeProgressChanged (package:flutter/src/widgets/dismissible.dart:502:44)
I/flutter (24587): #5      AnimationLocalListenersMixin.notifyListeners (package:flutter/src/animation/listener_helpers.dart:135:19)
I/flutter (24587): #6      AnimationController._tick (package:flutter/src/animation/animation_controller.dart:792:5)
I/flutter (24587): #7      Ticker._tick (package:flutter/src/scheduler/ticker.dart:237:12)
I/flutter (24587): #8      SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1074:15)
I/flutter (24587): #9      SchedulerBinding.handleBeginFrame.<anonymous closure> (package:flutter/src/scheduler/binding.dart:989:11)
I/flutter (24587): #10     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
I/flutter (24587): #11     SchedulerBinding.handleBeginFrame (package:flutter/src/scheduler/binding.dart:987:17)
I/flutter (24587): #12     SchedulerBinding._handleBeginFrame (package:flutter/src/scheduler/binding.dart:921:5)
I/flutter (24587): #16     _invoke1 (dart:ui/hooks.dart:275:10)
I/flutter (24587): #17     _beginFrame (dart:ui/hooks.dart:202:3)
I/flutter (24587): (elided 3 frames from dart:async)
I/flutter (24587):
I/flutter (24587): The AnimationController notifying listeners was:
I/flutter (24587):   AnimationController#56b89(⏭ 1.000; paused)

Yeah it's waiting the future to complete after the Snackbar (confirmDismiss) to know if it would animate back or resize and dismiss

logs
Restarted application in 416ms.
[VERBOSE-2:ui_dart_state.cc(184)] Unhandled Exception: 'package:flutter/src/widgets/dismissible.dart': Failed assertion: line 515 pos 12: '_resizeController == null': is not true.
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
#2      _DismissibleState._startResizeAnimation
 package:flutter/…/widgets/dismissible.dart
#3      _DismissibleState._handleDismissStatusChanged
 package:flutter/…/widgets/dismissible.dart
<asynchronous suspension>
[VERBOSE-2:ui_dart_state.cc(184)] Unhandled Exception: 'package:flutter/src/widgets/dismissible.dart': Failed assertion: line 515 pos 12: '_resizeController == null': is not true.
#0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
#1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
#2      _DismissibleState._startResizeAnimation
 package:flutter/…/widgets/dismissible.dart
#3      _DismissibleState._handleDismissStatusChanged
 package:flutter/…/widgets/dismissible.dart
<asynchronous suspension>

════════ Exception caught by animation library ═════════════════════════════════
The following assertion was thrown while notifying status listeners for AnimationController:
This widget has been unmounted, so the State no longer has a context (and should be considered defunct).

Consider canceling any active work during "dispose" or using the "mounted" getter to determine if the State is still active.
When the exception was thrown, this was the stack
#0      State.context.<anonymous closure>
 package:flutter/…/widgets/framework.dart
#1      State.context
 package:flutter/…/widgets/framework.dart
#2      AutomaticKeepAliveClientMixin._ensureKeepAlive
 package:flutter/…/widgets/automatic_keep_alive.dart
#3      AutomaticKeepAliveClientMixin.updateKeepAlive
 package:flutter/…/widgets/automatic_keep_alive.dart
#4      _DismissibleState._startResizeAnimation.<anonymous closure>
 package:flutter/…/widgets/dismissible.dart
...
The AnimationController notifying status listeners was: AnimationController#38c97(▶ 0.000)
════════════════════════════════════════════════════════════════════════════════
[VERBOSE-2:ui_dart_state.cc(184)] Unhandled Exception: setState() called after dispose(): _DismissibleState#5191d(lifecycle state: defunct, not mounted, tickers: tracking 1 ticker)
This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
#0      State.setState.<anonymous closure> (pack<…>

════════ Exception caught by animation library ═════════════════════════════════
This widget has been unmounted, so the State no longer has a context (and should be considered defunct).
════════════════════════════════════════════════════════════════════════════════

Launching lib/main.dart on iPhone 12 in debug mode...
 lib/main.dart
Xcode build done.                                           13.8s
Connecting to VM Service at ws://127.0.0.1:58836/ANzXsQi9TQM=/ws
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: setState() called after dispose(): _DismissibleState#56b35(lifecycle state: defunct, not mounted, tickers: tracking 1 ticker)
This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
#0      State.setState.<anonymous closure> (pack<…>

════════ Exception caught by animation library ═════════════════════════════════
The following NoSuchMethodError was thrown while notifying listeners for AnimationController:
The method 'dependOnInheritedWidgetOfExactType' was called on null.
Receiver: null
Tried calling: dependOnInheritedWidgetOfExactType<Directionality>()

When the exception was thrown, this was the stack
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
#1      Directionality.of
 package:flutter/…/widgets/basic.dart
#2      _DismissibleState._extentToDirection
 package:flutter/…/widgets/dismissible.dart
#3      _DismissibleState._dismissDirection
 package:flutter/…/widgets/dismissible.dart
#4      _DismissibleState._handleResizeProgressChanged
 package:flutter/…/widgets/dismissible.dart
...
The AnimationController notifying listeners was: AnimationController#0b972(⏭ 1.000; paused)
════════════════════════════════════════════════════════════════════════════════

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 (3 weeks 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.3)
    • Android SDK at /Volumes/Extreme/sdk
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Volumes/Extreme/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.18.0

[✓] Connected device (3 available)
    • RMX2001 (mobile)     • EUYTFEUSQSRGDA6D                     • android-arm64 • Android 10 (API 29)
    • Taha’s iPad (mobile) • 00008020-000255113EE8402E            • ios           • iOS 14.3
    • iPhone 12 (mobile)   • 12D8FF8E-2815-436E-9951-B8A6A42E4ACF • ios           • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator)

! Doctor found issues in 1 category.

[✓] Flutter (Channel master, 1.26.0-2.0.pre.145, on macOS 11.1 20C69 darwin-x64, locale en-GB)
    • Flutter version 1.26.0-2.0.pre.145 at /Users/tahatesser/Code/flutter_master
    • Framework revision 38fe7e2b1c (12 hours ago), 2020-12-28 21:39:03 -0500
    • Engine revision 892034dc6a
    • Dart version 2.12.0 (build 2.12.0-179.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Volumes/Extreme/sdk
    • Platform android-30, build-tools 30.0.3
    • ANDROID_HOME = /Volumes/Extreme/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)

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

[✓] Connected device (5 available)
    • RMX2001 (mobile)     • EUYTFEUSQSRGDA6D                     • android-arm64  • Android 10 (API 29)
    • Taha’s iPad (mobile) • 00008020-000255113EE8402E            • ios            • iOS 14.3
    • iPhone 12 (mobile)   • 12D8FF8E-2815-436E-9951-B8A6A42E4ACF • 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

• No issues found!

authors: EdwynZN TahaTesser VladyslavBondarenko


text:
image_picker not respecting locale

Im using image_picker and have correctly configured portuguese locale on MaterialApp like so:
  localizationsDelegates: [
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        supportedLocales: [
          const Locale('pt', 'BR'),
        ],

But on iOS when i use ImageSource.camera it is in English ("use photo", etc). Seems like a bug to me.
Is there a way to make this correct (portuguese)?
Flutter doctor:

flutter doctor -v
[✓] Flutter (Channel stable, 1.20.1, on Mac OS X 10.15.6 19G73, locale pt-BR)
    • Flutter version 1.20.1 at /Users/danvilela/flutter
    • Framework revision 2ae34518b8 (8 days ago), 2020-08-05 19:53:19 -0700
    • Engine revision c8e3b94853
    • Dart version 2.9.0

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
    • Android SDK at /Users/danvilela/Library/Android/sdk
    • Platform android-30, build-tools 30.0.0
    • 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-6222593)
    • All Android licenses accepted.

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

[✓] Android Studio (version 4.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 48.0.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build
      1.8.0_242-release-1644-b3-6222593)

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

[✓] Connected device (1 available)
    • iPhone 8 (mobile) • 5A353A88-24B3-469C-9C9B-D2542FCAE084 • ios •
      com.apple.CoreSimulator.SimRuntime.iOS-13-6 (simulator)

• No issues found!

Hi @dmvvilela,
Can you add below in info.plist and see if it resolves your issue ?
<key>CFBundleDevelopmentRegion</key>
<string>es</string>

There is already a Key there with the string: $(DEVELOPMENT_LANGUAGE)
Where can this be changed so i don't hardcode this?
(Also, es is for spanish.. brazilian portuguese is pt-BR)

@dmvvilela checkout this link and see if it works for you.
Thanks.

The thing is, for a multi language app this is not good enough.. Cause it can't be only english or only portuguese..

@dmvvilela I see what you are saying.
I tested on latest Stable (1.20.2) and indeed the text shows up in English, but not sure if providing only the localizationDelegates is enough for image_picker plugin to show up in specified language.

Yep, that is the problem.
For now my app is only portuguese, but i'm pretty sure i'll have to internationalize it soon.

CC @shihaohong

Hi,
my application is a multi language one so I really need another way to set the locale for this module.
Thank you

Hi. Faced the same problem.
And after many hours of searching, it unexpectedly helped in my case. Perhaps it will be useful for someone else.
Edit the file Info.plist manually by Android Studio or VS Code or other text editor.
Replace
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
By
CFBundleDevelopmentRegion

ru-RU
en-US

CFBundleLocalizations

ru-RU
en-US

Of course, specifying your localization in the format xx-XX and specifying the parameters MaterialApp supportedLocales and localizationsDelegates.

Hi. Faced the same problem.
And after many hours of searching, it unexpectedly helped in my case. Perhaps it will be useful for someone else.
Edit the file Info.plist manually by Android Studio or VS Code or other text editor.
Replace
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
By
CFBundleDevelopmentRegion

ru-RU
en-US

CFBundleLocalizations

ru-RU
en-US

Of course, specifying your localization in the format xx-XX and specifying the parameters MaterialApp supportedLocales and localizationsDelegates.

Hi everyone|
Flutter localization won't be modified for system text so modifying native locale is required, solution https://github.com/flutter/flutter/issues/63719#issuecomment-757053169 works perfectly, just tried with Chinese.
image_picker: ^0.7.0-nullsafety

flutter doctor -v
[✓] Flutter (Channel master, 1.27.0-5.0.pre.49, on macOS 11.2.1 20D74 darwin-x64, locale en-GB)
    • Flutter version 1.27.0-5.0.pre.49 at /Users/tahatesser/Code/flutter_master
    • Framework revision 23e41734e5 (5 hours ago), 2021-02-18 00:46:02 -0800
    • Engine revision 6993cb229b
    • Dart version 2.13.0 (build 2.13.0-30.0.dev)
[✗] 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.dev/docs/get-started/install/macos#android-setup for detailed instructions).
      If the Android SDK has been installed to a custom location, please use
      `flutter config --android-sdk` to update to that location.
[!] Xcode - develop for iOS and macOS
    • Xcode at /Volumes/Extreme/Xcode.app/Contents/Developer
    • Xcode 12.4, Build version 12D4e
    ✗ CocoaPods not installed.
        CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/platform-plugins
      To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] 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)
[✓] VS Code (version 1.53.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.19.0
[✓] Connected device (3 available)
    • Taha’s iPhone (mobile) • 00008020-001059882212002E • ios            • iOS 14.4
    • macOS (desktop)        • macos                     • darwin-x64     • macOS 11.2.1 20D74 darwin-x64
    • Chrome (web)           • chrome                    • web-javascript • Google Chrome 88.0.4324.182
! Doctor found issues in 2 categories.

Maybe there could be some solution in the package to use flutter localization and modify native locale
Thank you

Native UI element language is controlled by the languages set in the application's plist. The need to reflect supported languages in the application is documented here
Closing, as this is not an issue with the plugin; all native UI on iOS relies on the proper localization process having been followed.

authors: HansMuller TahaTesser darshankawar dmvvilela jpr0ger mediproductions stuartmorgan


text:
Why does setEnabledSystemUIOverlays refresh the ui?

Whenever I do SystemChrome.setEnabledSystemUIOverlays the images and scroll controller are initialized.
Removing the animation didn't solve the problem.
I have tried many other things besides this, but it has not been fixed.
This source code is the problematic part of my project.
import 'dart:async';

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:photo_view/photo_view.dart';
import 'package:provider/provider.dart';
import 'package:violet/database/user/record.dart';
import 'package:violet/locale/locale.dart';
import 'package:violet/other/dialogs.dart';
import 'package:violet/pages/viewer/viewer_page_provider.dart';

int currentPage = 0;

class NViewerPage extends StatelessWidget {
  NViewerPage();

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () {
        Navigator.pop(context, currentPage);
        return new Future(() => false);
      },
      child: _VerticalImageViewer(),
    );
  }
}

class _VerticalImageViewer extends StatefulWidget {
  @override
  __VerticalImageViewerState createState() => __VerticalImageViewerState();
}

class __VerticalImageViewerState extends State<_VerticalImageViewer>
    with SingleTickerProviderStateMixin {
  ViewerPageProvider _pageInfo;
  Timer _clearTimer;
  List<bool> _loaded;
  List<double> _cachedHeight;
  ScrollController _scroll = ScrollController();
  int _prevPage = 1;
  AnimationController _controller;

  @override
  void initState() {
    super.initState();

    // _clearTimer = Timer.periodic(Duration(seconds: 1), (timer) {
    //   imageCache.clearLiveImages();
    //   imageCache.clear();
    // });

    _scroll.addListener(() async {
      currentPage = offset2Page(_scroll.offset);
      if (_prevPage != currentPage) {
        setState(() {
          _prevPage = currentPage;
        });
      }
    });

    _controller = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 500),
    );

    Future.delayed(Duration(milliseconds: 500)).then((value) {
      if (_controller.isCompleted) {
        _controller.reverse();
      } else {
        _controller.forward();
      }
      _checkLatestRead();
    });
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    _pageInfo = Provider.of<ViewerPageProvider>(context);
    _loaded = List<bool>.filled(_pageInfo.uris.length, false);
    _cachedHeight = List<double>.filled(_pageInfo.uris.length, -1);
  }

  @override
  void dispose() {
    _controller.dispose();
    _scroll.dispose();
    _clearTimer.cancel();
    PaintingBinding.instance.imageCache.clear();
    _pageInfo.uris.forEach((element) async {
      await CachedNetworkImageProvider(element).evict();
    });
    SystemChrome.setEnabledSystemUIOverlays([
      SystemUiOverlay.top,
      SystemUiOverlay.bottom,
    ]);
    super.dispose();
  }

  int offset2Page(double offset) {
    double xx = 0.0;
    for (int i = 0; i < _cachedHeight.length; i++) {
      xx += _loaded[i] ? _cachedHeight[i] : 300;
      xx += 4;
      if (offset < xx) {
        return i + 1;
      }
    }
    return _cachedHeight.length;
  }

  double page2Offset(int page) {
    double xx = 0.0;
    for (int i = 0; i < page; i++) {
      xx += _loaded[i] ? _cachedHeight[i] : 300;
    }
    return xx;
  }

  @override
  Widget build(BuildContext context) {
    final height = MediaQuery.of(context).size.height;

    return AnnotatedRegion<SystemUiOverlayStyle>(
      value: SystemUiOverlayStyle(
        statusBarColor: Colors.transparent,
        systemNavigationBarColor: Colors.transparent,
      ),
      sized: false,
      child: Scaffold(
        resizeToAvoidBottomInset: false,
        resizeToAvoidBottomPadding: false,
        body: Stack(
          children: <Widget>[
            PhotoView.customChild(
              minScale: 1.0,
              child: Container(
                color: const Color(0xff444444),
                child: ListView.builder(
                  padding: EdgeInsets.zero,
                  itemCount: _pageInfo.uris.length,
                  controller: _scroll,
                  cacheExtent: height * 2,
                  itemBuilder: (context, index) {
                    return _networkImageItem(index);
                  },
                ),
              ),
            ),
            _touchArea(),
            _bottomAppBar(),
          ],
        ),
      ),
    );
  }

  bool _overlayOpend = false;
  _touchArea() {
    final height = MediaQuery.of(context).size.height;
    final width = MediaQuery.of(context).size.width;
    return Align(
      alignment: Alignment.center,
      child: Container(
        color: null,
        width: width / 3,
        height: height,
        child: GestureDetector(
          behavior: HitTestBehavior.translucent,
          onTap: () async {
            if (!_overlayOpend) {
              _prevPage = currentPage;
              if (_controller.isCompleted) {
                _controller.reverse();
              } else {
                _controller.forward();
              }
              SystemChrome.setEnabledSystemUIOverlays(
                  [SystemUiOverlay.bottom, SystemUiOverlay.top]);
            } else {
              if (_controller.isCompleted) {
                _controller.reverse();
              } else {
                _controller.forward();
              }
              SystemChrome.setEnabledSystemUIOverlays([]);
            }
            _overlayOpend = !_overlayOpend;
          },
        ),
      ),
    );
  }

  _networkImageItem(index) {
    final width = MediaQuery.of(context).size.width - 4;

    if (_loaded[index] && _cachedHeight[index] >= 0) {
      return _neworkImageView(index);
    }

    return FutureBuilder(
      future: _loaded[index]
          ? Future.value(1)
          : Future.delayed(Duration(milliseconds: 1000)).then((value) => 1),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return SizedBox(
            height: _loaded[index] ? _cachedHeight[index] : 300.0,
            child: Center(
              child: SizedBox(
                child: CircularProgressIndicator(),
                width: 30,
                height: 30,
              ),
            ),
          );
        }
        return FutureBuilder(
          future: _calculateImageDimension(_pageInfo.uris[index]),
          builder: (context, AsyncSnapshot<Size> snapshot) {
            if (snapshot.hasData) {
              _loaded[index] = true;
              _cachedHeight[index] = width / snapshot.data.aspectRatio;
            }
            return _neworkImageView(index);
          },
        );
      },
    );
  }

  _neworkImageView(index) {
    final width = MediaQuery.of(context).size.width - 4;
    return SizedBox(
      height: _loaded[index] ? _cachedHeight[index] : 300.0,
      width: width,
      child: CachedNetworkImage(
        height: _loaded[index] ? _cachedHeight[index] : 300.0,
        width: width,
        imageUrl: _pageInfo.uris[index],
        httpHeaders: _pageInfo.headers,
        fit: BoxFit.cover,
        fadeInDuration: Duration(microseconds: 500),
        fadeInCurve: Curves.easeIn,
        progressIndicatorBuilder: (context, string, progress) {
          return Center(
            child: SizedBox(
              child: CircularProgressIndicator(value: progress.progress),
              width: 30,
              height: 30,
            ),
          );
        },
      ),
    );
  }

  Future<Size> _calculateImageDimension(String url) async {
    Completer<Size> completer = Completer();
    Image image = new Image(
        image: CachedNetworkImageProvider(url, headers: _pageInfo.headers));
    image.image.resolve(ImageConfiguration()).addListener(
      ImageStreamListener(
        (ImageInfo image, bool synchronousCall) {
          var myImage = image.image;
          Size size = Size(myImage.width.toDouble(), myImage.height.toDouble());
          if (!completer.isCompleted) completer.complete(size);
        },
      ),
    );
    return completer.future;
  }

  _bottomAppBar() {
    final height = MediaQuery.of(context).size.height;
    final bottom = MediaQuery.of(context).padding.bottom;
    final mediaQuery = MediaQuery.of(context);
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) => Transform.translate(
        offset: Offset(0, _controller.value * (128)),
        child: Container(
          // height: 128,
          padding: EdgeInsets.only(
              top: height - bottom - 128,
              bottom: (mediaQuery.padding + mediaQuery.viewInsets).bottom),
          child: BottomAppBar(
            color: Colors.black.withOpacity(0.2),
            child: Container(
              height: 64,
              child: Column(
                  crossAxisAlignment: CrossAxisAlignment.stretch,
                  mainAxisAlignment: MainAxisAlignment.start,
                  children: [
                    Slider(
                      value: _prevPage.toDouble(),
                      max: _pageInfo.uris.length.toDouble(),
                      min: 1,
                      label: _prevPage.toString(),
                      divisions: _pageInfo.uris.length,
                      onChanged: (value) {
                        _scroll.jumpTo(page2Offset(_prevPage - 1) - 32);
                        setState(() {
                          _prevPage = value.toInt();
                        });
                      },
                    ),
                  ]),
            ),
          ),
        ),
      ),
    );
  }
}

It's hard to understand.
It simply activates the status bar and the bottom navigation bar.
Why do this need to refresh the entire UI?

@violet-dev

Why do this need to refresh the entire UI?

does it?

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

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

class MyApp extends StatelessWidget {
  const MyApp();
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  bool _overlay = false;

  void _overlayON() {
    SystemChrome.setEnabledSystemUIOverlays([]);
    setState(() => _overlay = true);
  }

  void _overlayOFF() {
    SystemChrome.setEnabledSystemUIOverlays([
      SystemUiOverlay.top,
      SystemUiOverlay.bottom,
    ]);
    setState(() => _overlay = false);
  }

  void _incrementCounter() {
    setState(() => _counter++);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
            Switch(
              value: _overlay,
              onChanged: (_) => _overlay ? _overlayOFF() : _overlayON(),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

@iapicca Thanks for the Answer!
I changed all the logic and found an image provider caching bug in the process.
It was temporarily taken, but it seems to be a problem to be solved by the Flutter development team.

@violet-dev
please note that cached_network_image is a 3rd party plugin
related issues should be opened here

@iapicca no cached_network_image
I'm telling you this
// flutter/lib/src/painting/binding.dart

/// The singleton that implements the Flutter framework's image cache.
///
/// The cache is used internally by [ImageProvider] and should generally not be
/// accessed directly.
///
/// The image cache is created during startup by the [PaintingBinding]'s
/// [PaintingBinding.createImageCache] method.
ImageCache? get imageCache => PaintingBinding.instance!.imageCache

    _clearTimer = Timer.periodic(Duration(seconds: 1), (timer) {
      imageCache.clearLiveImages();
      imageCache.clear();
    });

Memory leak is seriously, so if I do not evict every second, my app will broken.

I had been having this problem two months ago, but I gave up because there was no progress after leaving any issues.

authors: iapicca violet-dev


text:
flutter pub get --offline didn't work in 1.22.4 stable

I used to use pub get --offline in my project.
Because I cann't access pub.dev on CI server. The --offline mode is very important for me.
I can correct use with version 1.17.5. But when I use it on 1.22.4 the fllowing alert came out.
It seems like the vector_math version from origin sdk is not available.
Can you upgrade the version to make --offline work correctly?
Because every version of flutter_localizations from sdk depends on vector_math any which is forbidden, flutter_localizations from sdk is forbidden.
So, because flutter_module depends on flutter_localizations any from sdk, version solving failed.
pub get failed (server unavailable) -- attempting retry 1 in 1 second...
Because every version of flutter_localizations from sdk depends on vector_math any which is forbidden, flutter_localizations from sdk is forbidden.
So, because flutter_module depends on flutter_localizations any from sdk, version solving failed.

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 1.22.4, on Microsoft Windows [Version 10.0.18363.720], locale zh-CN)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.1)
[!] Android Studio (version 4.1.0)
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
[!] Connected device
! No devices available

@leo7723
I think this issue belongs to dart-lang/pub. Please consider opening this issue here : https://github.com/dart-lang/pub/issues
Closing this from here. If you disagree, or think this is a Flutter issue and not dart-lang, write in comments and I'll reopen it.
Thanks.


text:
A render exception occurred in the flutter in tabbarview

The render exception occurred in the flutter. The background color should have been displayed in tabbarview Color.fromRGBO (242, 242, 244, 1); the color of the block is shown in the place of the Color.fromRGBO (255, 255, 255, 1);
video
https://user-images.githubusercontent.com/44134842/105112053-25108f00-5afd-11eb-8f4a-accfe7ae66c2.mp4
project is
message.zip
code is

code sample
class cloudManage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _cloudManage();
  }
}

class _cloudManage extends State<cloudManage>
    with SingleTickerProviderStateMixin {
  TabController tc;

  _cloudManage() {
    this.tc =
        new TabController(length: serverElemMap.values.length, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Container(
          padding: EdgeInsets.fromLTRB(
            paddingBorder.toDouble(),
            topMargin.toDouble(),
            paddingBorder.toDouble(),
            10,
          ),
          child: Row(
            children: [
              Expanded(
                child: TabBar(
                  physics: BouncingScrollPhysics(
                      parent: AlwaysScrollableScrollPhysics()),
                  isScrollable: true,
                  tabs: serverElemMap.values
                      .map((value) => TextOrdinary(value.serverName))
                      .toList(),
                  controller: tc,
                ),
              )
            ],
          ),
          alignment: Alignment.centerLeft,
        ),
        Expanded(
          child: Container(
            child: TabBarView(
              physics: BouncingScrollPhysics(
                  parent: AlwaysScrollableScrollPhysics()),
              children: serverElemMap.values.map((e) {
                return Column(
                  children: [
                    ...e.serverUserList.map((e) => _userElem(e)).toList()
                  ],
                );
              }).toList(),
              controller: tc,
            ),
            margin: EdgeInsets.symmetric(horizontal: paddingBorder.toDouble()),
          ),
        ),
      ],
    );
  }
}

dev android is android10 It's a physical machine
I have the same problem with Android 11 AVD
Flutter 1.22.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 7891006299 (6 weeks ago) • 2020-12-10 11:54:40 -0800
Engine • revision ae90085a84
Tools • Dart 2.10.4
[√] Flutter (Channel stable, 1.22.5, on Microsoft Windows [Version 10.0.17763.1697], locale zh-CN)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
[!] Android Studio (version 4.1.0)
X Flutter plugin not installed; this adds Flutter specific functionality.
X Dart plugin not installed; this adds Dart specific functionality.
[!] VS Code (version 1.52.1)
X Flutter extension not installed; install from
https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[√] Connected device (1 available)
! Doctor found issues in 2 categories.

Hi @au-top
Can you please provide your flutter run --verbose, the actual vs expected results and a minimal complete reproducible code sample? The code you provide seems to be a a big project that makes things hard to find the real issue. Please provide a runnable code that focus on reproducing the issue only.
Thank you

Hi @au-top
Can you please provide your flutter run --verbose, the actual vs expected results and a minimal complete reproducible code sample? The code you provide seems to be a a big project that makes things hard to find the real issue. Please provide a runnable code that focus on reproducing the issue only.
Thank you

Without additional information, we are unfortunately not sure how to resolve this issue.
We are therefore reluctantly going to close this bug for now.
Please don't hesitate to comment on the bug if you have any more information for us; we will reopen it right away!
Thanks for your contribution.
Could everyone who still has this problem please file a new issue with the exact description of what happens, logs, and the output of flutter doctor -v.
All system setups can be slightly different, so it's always better to open new issues and reference related issues.

authors: au-top pedromassangocode


text:
Flutter tools should pass package:flutter the Dart DevTools Server url immediately on app startup

Currently there may be issues if the DevTools Server has not started in time and there may also be issues due to needing to wait for the service extension to be registered.
Either flutter tools needs to wait for Dart DevTools to launch (would regress startup performance) or flutter tools needs to always pick the Dart DevTools port so that it knows what port Dart DevTools will launch on before it is launched.
In addition, there is an issue that VM Service extension setting the devtools url will likely not be registered until the first frame is rendered causing 1 frame to possibly generate errors without a valid devtools url to display error messages with.
Possible solution:

Extend the Dart VM Service to allow calling service extensions before they have been registered. When a service extension is registered it will receive the value sent before it was registered.

Fyi @kenzieschmoll @bkonyi

Fyi @kenzieschmoll @bkonyi

https://github.com/flutter/flutter/pull/74859
Illustrated a bug in the current approach to wait for DevTools Server before starting the Flutter app.

https://github.com/flutter/flutter/pull/74859
Illustrated a bug in the current approach to wait for DevTools Server before starting the Flutter app.

Is it really that critical that we have the DevTools URL on app startup?

Is it really that critical that we have the DevTools URL on app startup?

Not critical but nice for consistency. It could be confusing for users if the same error sometimes has extra helpful debugging data but sometimes doesn't.
We need the DevTools URL on app startup to have consistent error display for the first frame and subsequent frames.
The current behavior should result in only error messages from after the first frame(s) linking to DevTools.

Not critical but nice for consistency. It could be confusing for users if the same error sometimes has extra helpful debugging data but sometimes doesn't.
We need the DevTools URL on app startup to have consistent error display for the first frame and subsequent frames.
The current behavior should result in only error messages from after the first frame(s) linking to DevTools.

There's a message that comes up when the DevTools are loaded; messages before that don't have it and messages after that do. That seems pretty self-explanatory. I guess it is also missing from messages immediately after hot restart before we have time to give the app the data, but again that's pretty consistent so would it really be that confusing? I dunno.

There's a message that comes up when the DevTools are loaded; messages before that don't have it and messages after that do. That seems pretty self-explanatory. I guess it is also missing from messages immediately after hot restart before we have time to give the app the data, but again that's pretty consistent so would it really be that confusing? I dunno.

Correct you also have the issue for the first frame after a hot restart.
This isn't that high priority unless we get evidence from analytics that these links to DevTools are being used a lot.

Correct you also have the issue for the first frame after a hot restart.
This isn't that high priority unless we get evidence from analytics that these links to DevTools are being used a lot.