这是一个示例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个小部件,因为这是唯一修改的小部件。请在此处帮助确定问题。