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 要做的工作最少,因为 ListItemListView.

有更少的 children

Provider 不影响 Flutter 构建 widget 的方式。使用 Provider 时,您仍然会犯同样的错误,即过于频繁地重建太多小部件。

Provider 确实但是为您提供了一些工具来重建较小的小部件。一个例子是 Selector.