Flutter 供应商使用
Flutter provider use
我看过教程中的一段代码,用于在 ListView 中创建最喜欢的 selection。但是我看到它没有使用提供程序,我想知道使用它是否更好。我想通过单击每个项目上的按钮来创建最喜欢的 selection,并且我想在另一个 ListView 中检索 select 项目。这是教程中的代码:
main.dart
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
import 'package:words/favorite_words_route.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Likely Words',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Likely Words'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> words = nouns.take(40).toList();
List<String> savedWords = List<String>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: <Widget>[
Badge(
badgeContent: Text('${savedWords.length}'),
toAnimate: false,
position: BadgePosition.topRight(top: 0, right: 0),
child: IconButton(
icon: Icon(Icons.bookmark),
onPressed: () => pushToFavoriteWordsRoute(context),
),
),
],
),
body: ListView.separated(
itemCount: words.length,
separatorBuilder: (BuildContext context, int index) => Divider(),
itemBuilder: (BuildContext context, int index) {
String word = words[index];
bool isSaved = savedWords.contains(word);
return ListTile(
title: Text(word),
trailing: Icon(
isSaved ? Icons.favorite : Icons.favorite_border,
color: isSaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (isSaved) {
savedWords.remove(word);
} else {
savedWords.add(word);
}
});
},
);
},
),
);
}
Future pushToFavoriteWordsRoute(BuildContext context) {
return Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => FavoriteWordsRoute(
favoriteItems: savedWords,
),
),
);
}
}
favorite_words_route.dart
import 'package:flutter/material.dart';
class FavoriteWordsRoute extends StatelessWidget {
final List<String> favoriteItems;
const FavoriteWordsRoute({Key key, @required this.favoriteItems}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Favorites words'),
),
body: ListView.separated(
itemCount: favoriteItems.length,
separatorBuilder: (BuildContext context, int index) => Divider(),
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text(favoriteItems[index]),
),
),
);
}
}
如果提供商更好,请告诉我性能。
提供商不会让性能更好。
调用 setState
重建一个小部件。如果重建一个小部件,at-worst 它的所有 children 都会被构建。因此,如果我构建一个列表,所有 list-items 都可能会重建。
在这种情况下可以进行的优化是从 ListItem
而不是 MyHomePage
小部件内部调用 setState
。这让 Flutter 要做的工作最少,因为 ListItem
比 ListView
.
有更少的 children
Provider 不影响 Flutter 构建 widget 的方式。使用 Provider 时,您仍然会犯同样的错误,即过于频繁地重建太多小部件。
Provider 确实但是为您提供了一些工具来重建较小的小部件。一个例子是 Selector.
我看过教程中的一段代码,用于在 ListView 中创建最喜欢的 selection。但是我看到它没有使用提供程序,我想知道使用它是否更好。我想通过单击每个项目上的按钮来创建最喜欢的 selection,并且我想在另一个 ListView 中检索 select 项目。这是教程中的代码:
main.dart
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
import 'package:words/favorite_words_route.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Likely Words',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Likely Words'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<String> words = nouns.take(40).toList();
List<String> savedWords = List<String>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: <Widget>[
Badge(
badgeContent: Text('${savedWords.length}'),
toAnimate: false,
position: BadgePosition.topRight(top: 0, right: 0),
child: IconButton(
icon: Icon(Icons.bookmark),
onPressed: () => pushToFavoriteWordsRoute(context),
),
),
],
),
body: ListView.separated(
itemCount: words.length,
separatorBuilder: (BuildContext context, int index) => Divider(),
itemBuilder: (BuildContext context, int index) {
String word = words[index];
bool isSaved = savedWords.contains(word);
return ListTile(
title: Text(word),
trailing: Icon(
isSaved ? Icons.favorite : Icons.favorite_border,
color: isSaved ? Colors.red : null,
),
onTap: () {
setState(() {
if (isSaved) {
savedWords.remove(word);
} else {
savedWords.add(word);
}
});
},
);
},
),
);
}
Future pushToFavoriteWordsRoute(BuildContext context) {
return Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => FavoriteWordsRoute(
favoriteItems: savedWords,
),
),
);
}
}
favorite_words_route.dart
import 'package:flutter/material.dart';
class FavoriteWordsRoute extends StatelessWidget {
final List<String> favoriteItems;
const FavoriteWordsRoute({Key key, @required this.favoriteItems}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Favorites words'),
),
body: ListView.separated(
itemCount: favoriteItems.length,
separatorBuilder: (BuildContext context, int index) => Divider(),
itemBuilder: (BuildContext context, int index) => ListTile(
title: Text(favoriteItems[index]),
),
),
);
}
}
如果提供商更好,请告诉我性能。
提供商不会让性能更好。
调用 setState
重建一个小部件。如果重建一个小部件,at-worst 它的所有 children 都会被构建。因此,如果我构建一个列表,所有 list-items 都可能会重建。
在这种情况下可以进行的优化是从 ListItem
而不是 MyHomePage
小部件内部调用 setState
。这让 Flutter 要做的工作最少,因为 ListItem
比 ListView
.
Provider 不影响 Flutter 构建 widget 的方式。使用 Provider 时,您仍然会犯同样的错误,即过于频繁地重建太多小部件。
Provider 确实但是为您提供了一些工具来重建较小的小部件。一个例子是 Selector.