为什么使用 context.select 代替 context.watch 会导致范围错误?

时间:2021-04-26 04:16:59

标签: flutter dart flutter-provider

此代码有效。但是,如果我将 context.watch 中的 ListView.builder 替换为 context.select,当点击带有子项“单击此处从列表中清除”的 ElevatedButton 时会产生范围错误.想知道为什么会这样。

这是错误: [以下 RangeError 在构建 _InheritedProviderScope(dirty, value: Instance of 'Hi', listen to value) 时被抛出: RangeError (index): Invalid value: Valid value range is empty: 9]

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Hi(),
      child: MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          initialRoute: '/',
          routes: {
            '/': (context) => FirstPage(),
          }),
    );
  }
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('this is a ListView.builder/ ProxyProxyProviderTest2'),
        ),
        body: Column(
          children: [
            Row(
              children: [
                ElevatedButton(
                  onPressed: () {
                    context.read<Hi>().addToList();
                  },
                  child: Text('click here to add to list'),
                ),
                ElevatedButton(
                  onPressed: () {
                    context.read<Hi>().clearFromList();
                    print('clear has been clicked');
                  },
                  child: Text('click here to clear the list'),
                ),
              ],
            ),
            SizedBox(
              height: 500,
              child: ListView.builder(
                itemCount: context.select((Hi h) => h.original.length),
                itemBuilder: (context, index) {
                  return Builder(
                    builder: (context) => ListTile(
                      title:
                          Text(context.watch<Hi>().original[index].toString()),
                    ),
                  );
                },
              ),
            )
          ],
        ));
  }
}

class Hi extends ChangeNotifier {
  List<int> original = [];
  var random = Random();
  void addToList() {
    int i = 0;
    while (i < 10) {
      original.add(random.nextInt(10));
      i++;
      notifyListeners();
    }
  }

  void clearFromList() {
    original.clear();
    notifyListeners();
  }
}

0 个答案:

没有答案