-
Notifications
You must be signed in to change notification settings - Fork 27.2k
-
Notifications
You must be signed in to change notification settings - Fork 27.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Page with SingleTickerProviderStateMixin cause unnecessary build #72908
Comments
@6a209 void toPageB() {
tabController.animateTo(1);
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
return PageB();
}));
} the issue might be with your code rather than being a bug with flutter |
@iapicca you can remove tabController.animateTo(1) the build function also call,if “tabController.animateTo(1)” will cause dependence page‘s state build i think is a bug。 |
i read the source code,it's because SingleTickerProviderStateMixin override didChangeDependencies()
TickerMode.of()
_EffectiveTickerMode is a InheritedWidget, it's will add PageA's element to InheritedElement's _dependents |
Hi @6a209 In Flutter there is no guarantees about how many times the build method will be called and this should not cause any side effect in your implementation. |
@pedromassangocode |
CC @goderbauer |
Hi @pedromassangocode, My App Index Page‘s state with the SingleTickerProviderStateMixin, I found is has jank when navigator to other page, i use timeline tools found the page's state rebuild when navigator。 Index page is complex so it's build take many time |
Hi @6a209 This may have the same cause as #64444 - #64444 (comment). Codeimport 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PageA(title: 'Flutter Demo Home Page'),
);
}
}
class PageA extends StatefulWidget {
PageA({Key key, this.title}) : super(key: key);
final String title;
@override
_PageAState createState() => _PageAState();
}
class _PageAState extends State<PageA>
with SingleTickerProviderStateMixin {
TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this);
}
void toPageB() {
//tabController.animateTo(1);
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
return PageB();
}));
}
@override
Widget build(BuildContext context) {
print("Page A");
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: TabBar(
tabs: [
Text(
"Tab A",
style: Theme.of(context).textTheme.bodyText1,
),
Text(
"Tab B",
style: Theme.of(context).textTheme.bodyText1,
)
],
controller: tabController,
),
),
floatingActionButton: FloatingActionButton(
onPressed: toPageB,
child: Icon(Icons.add),
),
);
}
}
class PageB extends StatelessWidget {
@override
Widget build(BuildContext context) {
print("Page B");
return Scaffold(
appBar: AppBar(
title: Text("Page A"),
),
body: Container(
child: Center(
child: Text("Page A"),
),
));
}
} flutter doctor -v
@iapicca see https://api.flutter.dev/flutter/widgets/State/build.html it says:
|
My understanding of the doc is that |
I meant we don't know how many times it will be called because of external dependencies while the app is running and that it should not cause any side-effect, if it does cause a side-effect then it is an issue either in Flutter or in user's code. @iapicca sorry if I said it wrong, please see a more complete answer at https://stackoverflow.com/a/52249579. |
I can confirm this causes some performances issues in my app when navigating between heavy pages. From what I understood, Maybe this could be done with a lighter dependency mechanism than |
Having this issue on my app, I have a complex tree structure and it causes UI jank on page navigation because |
I did answer the question in stackoverflow This is the solution I used before. Change your Page A like
And add a new class CustomTabBar
It should fix the issue that Page A rebuild |
as mentioned in #64444 by @6a209, we can override this method and ignore the super call to avoid rebuilds. Which also makes sense wrt @jyardin 's explanation. However, would this cause any problems with TickerProviderStateMixin mixins? Any help would be very appreciated. |
I can't seem to reproduce the issue using the code in #72908 (comment) along with the steps provided. When I navigate to page B and return, Page A is not printed in my logs. See the logs below. Page A is only printed when it is built. I'll be closing this as fixed since I cannot reproduce the bug. If anyone still faces this issue on the latest versions of flutter, kindly file a new issue and provide the code sample along with detailed steps required to reproduce. Thank you logs
updated sampleimport 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const PageA(title: 'Flutter Demo Home Page'),
);
}
}
class PageA extends StatefulWidget {
const PageA({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<PageA> createState() => _PageAState();
}
class _PageAState extends State<PageA> with SingleTickerProviderStateMixin {
late TabController tabController;
@override
void initState() {
super.initState();
tabController = TabController(length: 2, vsync: this);
}
void toPageB() {
//tabController.animateTo(1);
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
return const PageB();
}));
}
@override
Widget build(BuildContext context) {
print("Page A");
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: TabBar(
tabs: [
Text(
"Tab A",
style: Theme.of(context).textTheme.bodyText1,
),
Text(
"Tab B",
style: Theme.of(context).textTheme.bodyText1,
)
],
controller: tabController,
),
),
floatingActionButton: FloatingActionButton(
onPressed: toPageB,
child: const Icon(Icons.add),
),
);
}
}
class PageB extends StatelessWidget {
const PageB({super.key});
@override
Widget build(BuildContext context) {
print("Page B");
return Scaffold(
appBar: AppBar(
title: const Text("Page A"),
),
body: const Center(
child: Text("Page A"),
),
);
}
} flutter doctor -v
|
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of |
Here is my test code , pageA Navigator to pageB, _PageAState will call build
Code
The text was updated successfully, but these errors were encountered: