flutter ListView的有状态与无状态小部件,生成器项

fnx2tebb  于 2023-05-01  发布在  Flutter
关注(0)|答案(2)|浏览(149)

请注意,这是针对ListView.builder项的,而不是一般的无状态与有状态小部件的讨论。
无状态列表视图生成器项:

  • 优点
  • 我假设每个项目都可以在一个大列表中快速重用,因为它们不包含任何状态
  • 缺点
  • 对任何项目的任何更改都需要在列表视图中调用setState

有状态列表视图生成器项:

  • 优点
  • 正如Performance best practices中所建议的,我们可以通过item小部件中的setState调用来更新每个项目,这比在整个列表视图小部件上调用setState对性能的影响要小得多。
  • 缺点
  • 由于每一行现在都有自己的状态,我猜它们不能被重用?

那么你会推荐哪一个呢?

hs1ihplo

hs1ihplo1#

  • 无状态的ListView构建器项非常高效,因为它们可以在大型列表中快速重用,但是对任何项的任何更改都需要在整个ListView小部件上调用setState
  • 有状态的ListView构建器项允许通过item小部件内的setState调用来更新每个项,这比在整个ListView小部件上调用setState对性能的影响要小,但每行都有自己的状态,不能重用。
  • 建议:*

使用最适合您的特定用例和性能要求的方法。如果您需要频繁地更新单个项,并且ListView很大,请考虑使用有状态项。如果您有一个较小的ListView,并且不需要频繁地更新单个项目,则无状态项目可能就足够了。
您可以尝试为ListView.builder中的每个Stateful项指定一个唯一的Key以重用它们。

xqk2d5yq

xqk2d5yq2#

如果ListView项很简单,没有任何内部状态或交互性,那么使用无状态小部件会更有性能,也更容易管理。如果项目具有内部状态、交互性或更复杂的行为,则使用Stateful小部件将是更好的选择。
请记住,Flutter针对快速UI更新进行了优化,因此Stateful与Stateless ListView的性能影响。构建器项的数量并不重要,尤其是对于中小型的项列表。始终建议您分析应用程序并检查性能指标。
也不要忘记继承的小部件
继承的小部件提供了一种沿小部件树向下传递数据的方法,而不需要手动传递数据通过每一层。当您想要在多个小部件之间共享公共信息或状态,而不必在信息发生变化时重新构建整个小部件树时,继承的小部件非常有用。
这里有一个例子

class CounterProvider extends InheritedWidget {
  final int counter;
  final VoidCallback increment;

  const CounterProvider({
    Key? key,
    required this.counter,
    required this.increment,
    required Widget child,
  }) : super(key: key, child: child);

  static CounterProvider of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<CounterProvider>()!;
  }

  @override
  bool updateShouldNotify(CounterProvider old) => counter != old.counter;
}

Package ListView。使用自定义InheritedWidget创建一个builder,传递必要的数据和方法:

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('InheritedWidget Example')),
      body: CounterProvider(
        counter: _counter,
        increment: _incrementCounter,
        child: ListView.builder(
          itemCount: 10,
          itemBuilder: (context, index) => MyListItem(index),
        ),
      ),
    );
  }
}

从ListView中的InheritedWidget访问数据。建筑商项目:

class MyListItem extends StatelessWidget {
  final int index;

  MyListItem(this.index);

  @override
  Widget build(BuildContext context) {
    final counterProvider = CounterProvider.of(context);

    return ListTile(
      title: Text('Item $index'),
      subtitle: Text('Counter: ${counterProvider.counter}'),
      onTap: () {
        counterProvider.increment();
      },
    );
  }
}

在本例中,我们使用InheritedWidget在所有ListView中管理和共享计数器值。生成器项目。每个项都可以访问计数器和增量方法,而不必通过构造函数显式传递它们。
继承的小部件可以很好地与无状态和有状态ListView一起使用。构建器项,具体取决于您的特定用例。它们可以帮助您管理多个小部件之间的共享状态,而无需在数据更改时重新构建整个树。
这个问题真的没有正确的答案。你几乎必须做什么是最适合你的使用情况。

相关问题