J'ai un PageView utilisé avec un BottomNavigationBar afin que je puisse avoir des onglets glissants et tapables avec une barre inférieure plutôt que la barre de navigation normale. Ensuite, j'ai deux onglets / pages que vous pouvez parcourir. L'un a un formulaire avec 4 éléments d'interface utilisateur et l'autre n'a pas encore d'éléments d'interface utilisateur. Tout fonctionne bien mais les performances de la PageView sont très mauvaises.
Lorsque je glisse entre les pages, c'est extrêmement lent et nerveux au début, certainement pas les 60 images par seconde promis par Flutter. Probablement même pas 30. Après avoir glissé plusieurs fois, les performances s'améliorent de plus en plus jusqu'à ce qu'elles ressemblent presque à une application native normale.
Voici ma classe de page qui comprend le PageView , BottomNavigationBar et la logique qui les relie. est-ce que quelqu'un sait comment je peux améliorer les performances de PageView?
class _TabbarPageState extends State<TabbarPage> {
int _index = 0;
final controller = PageController(
initialPage: 0,
keepPage: true,
);
final _tabPages = <Widget>[
StartPage(),
OtherPage(),
];
final _tabs = <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.play_arrow),
title: Text('Start'),
),
BottomNavigationBarItem(
icon: Icon(Icons.accessibility_new),
title: Text('Other'),
)
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: PageView(
controller: controller,
children: _tabPages,
onPageChanged: _onPageChanged,
),
bottomNavigationBar: BottomNavigationBar(
items: _tabs,
onTap: _onTabTapped,
currentIndex: _index,
),
floatingActionButton: _index != 1
? null
: FloatingActionButton(
onPressed: () {},
tooltip: 'Test',
child: Icon(Icons.add),
),
);
}
void _onTabTapped(int index) {
controller.animateToPage(
index,
duration: Duration(milliseconds: 300),
curve: Curves.ease,
);
setState(() {
_index = index;
});
}
void _onPageChanged(int index) {
setState(() {
_index = index;
});
}
}
4 Réponses :
Assurez-vous de tester les performances avec des versions de profil ou de version uniquement. Évaluer les performances avec les versions de débogage n'a aucun sens.
Désolé mais la réponse de Günter ne m'a pas aidé! Vous devez définir la physique: AlwaysScrollableScrollPhysics () Et vos performances augmentent.
A travaillé pour moi 👍
Je suis nouveau dans le flutter, s'il vous plaît dites-moi si c'est faux.
J'ai le même problème, voici mon effort. Wors pour moi.
class HomePage extends StatefulWidget {
@override
State createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
var _currentIndex = 1;
var _pageController = PageController(initialPage: 1);
var _todoPage, _inProgressPage, _donePage, _userPage;
@override
void initState() {
this._currentIndex = 1;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView.builder(
controller: this._pageController,
onPageChanged: (index) {
setState(() {
this._currentIndex = index.clamp(0, 3);
});
},
itemCount: 4,
itemBuilder: (context, index) {
if (index == 0) return this.todoPage();
if (index == 1) return this.inProgressPage();
if (index == 2) return this.donePage();
if (index == 3) return this.userPage();
return null;
},
),
bottomNavigationBar: buildBottomNavigationBar(),
);
}
Widget buildBottomNavigationBar() {
return BottomNavigationBar(
showUnselectedLabels: false,
items: [
BottomNavigationBarItem(title: Text("å¾
å"), icon: Icon(Icons.assignment)),
BottomNavigationBarItem(title: Text("è¿è¡"), icon: Icon(Icons.blur_on)),
BottomNavigationBarItem(title: Text("宿"), icon: Icon(Icons.date_range)),
BottomNavigationBarItem(title: Text("æç"), icon: Icon(Icons.account_circle)),
],
currentIndex: this._currentIndex,
onTap: (index) {
setState(() {
this._currentIndex = index.clamp(0, 3);
});
_pageController.jumpToPage(this._currentIndex);
},
);
}
Widget todoPage() {
if (this._todoPage == null) this._todoPage = TodoPage();
return this._todoPage;
}
Widget inProgressPage() {
if (this._inProgressPage == null) this._inProgressPage = InProgressPage();
return this._inProgressPage;
}
Widget donePage() {
if (this._donePage == null) this._donePage = DonePage();
return this._donePage;
}
Widget userPage() {
if (this._userPage == null) this._userPage = UserPage();
return this._userPage;
}
}
Je mets simplement en cache les pages que les pages vues contiennent. ce VRAIMENT lisse ma page vue beaucoup, comme native. mais empêcherait hotreload (ref: Comment gérer la construction de widget indésirable? a >) ,.
Cela a-t-il fonctionné à la fin ou était-ce juste une solution temporaire? Je suppose que ce sera un problème de publier des mises à jour sur les pages en cache.
Essayez ce hack, Appliquez viewportFraction à votre contrôleur avec la valeur 0.99 (cela peut être 0.999 ou 0.9999 hit et essayez jusqu'à ce que vous obteniez le résultat souhaité)
final controller = PageController( viewportFraction: 0.99 );
Assurez-vous de tester les performances avec des versions de profil ou de version uniquement. L'évaluation des performances avec les versions de débogage n'a aucun sens.
Ouais, j'aurais dû l'exécuter en mode profil en premier. Les performances sont sans faille dans ce mode et ce mode de sortie. Merci pour la suggestion. Si vous souhaitez publier une réponse en mode profil ou en mode version, je la marquerai comme acceptée.