Proivder的Selector重建所有小部件

时间:2020-06-08 06:41:27

标签: flutter flutter-provider

这是一个示例ListView来演示我的问题。用户单击按钮时应该更新的特定小部件。 我正在使用提供程序包中的选择器。单击该按钮时,将重建所有的DataTile小部件,而不仅仅是第5个。

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

import 'models.dart';

void main() {
  final model = DataModel();
  model.reload();

  runApp(
    ChangeNotifierProvider.value(
      value: model,
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

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

  void _incrementCounter(DataModel dataModel) {
    dataModel.modify(5);
  }

  @override
  Widget build(BuildContext context) {
    print("built my home page");
    final dataModel = Provider.of<DataModel>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
        itemCount: dataModel.all.length,
        itemBuilder: (_, index) => Selector<DataModel, Data>(
          selector: (_, model) => model.get(index),
          builder: (_, data, __) => DataTile(data),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _incrementCounter(dataModel),
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class DataTile extends StatelessWidget {
  final Data data;

  DataTile(this.data);

  @override
  Widget build(BuildContext context) {
    print("built Data Tile: ${data.id}");
    return ListTile(
      leading: Text(data.id.toString()),
      title: Text(data.leading),
      trailing: Text(data.trailing),
    );
  }
}




import 'package:flutter/foundation.dart';

class Data with ChangeNotifier{
  final int id;
  final String leading;
  final String trailing;

  Data(this.id, this.leading, this.trailing);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Data &&
          runtimeType == other.runtimeType &&
          id == other.id &&
          leading == other.leading &&
          trailing == other.trailing;

  @override
  int get hashCode => id.hashCode ^ leading.hashCode ^ trailing.hashCode;
}

class DataModel with ChangeNotifier {

  Map<int, Data> _dataList = {};

  void reload() {

    final list = List.generate(10, (index) => Data(index, "leading-$index", "trailing-$index"));

    for(var data in list){
      _dataList[data.id] = data;
    }

    notifyListeners();
  }

  List<Data> get all => _dataList.values.toList(growable: false);

  Data get(int index) => _dataList[index];

  void modify(int index) {
    print("modifying: $index");
    final current = _dataList[index];
    final newId = _dataList.length +1;
    final data = Data(newId, "${current.leading}, newId: $newId", current.leading);
    _dataList[index] = data;
    notifyListeners();
  }

}


我的期望是单击按钮仅重建第5个小部件,因为这是唯一修改的小部件。请在此处帮助确定问题。

0 个答案:

没有答案