首页 > 解决方案 > Flutter 提供者使用

问题描述

我从教程中看到了一个代码,用于在 ListView 中创建最喜欢的选择。但是我看到它不使用提供程序,我想知道使用它是否更好。我想通过单击每个项目上的按钮来创建最喜欢的选择,并且我想在另一个 ListView 中检索选择的项目。这是教程中的代码:

主要.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,
        ),
      ),
    );
  }
}

favourite_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]),
        ),
      ),
    );
  }
}

如果提供商更好,请告诉我性能。

标签: flutterdartprovider

解决方案


提供者不会使性能更好。

调用setState重建一个小部件。如果一个小部件被重建,最坏的情况是它的所有孩子都被构建了。因此,如果我建立一个列表,所有列表项都可能重建。

在这种情况下可以进行的优化是setState从内部调用ListItem而不是MyHomePage小部件。这让 Flutter 要做的工作最少,因为ListItem它的孩子比ListView.

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

然而, Provider确实为您提供了一些工具来重建较小的小部件。一个例子是选择器


推荐阅读