我在 Flutter 上关注了示例应用程序 https://codelabs.developers.google.com/codelabs/first-flutter-app-pt2/#0
并注意到每次我单击该行(将单词对设为最爱并在其旁边显示红心)时,整个 ListView 都会重建。 认为重建整个列表可能效率低下,因此我修改了示例中的原始代码,以便只有图 block 状态发生变化,并认为这只会重新绘制图 block 。我看到状态发生了变化,但图 block 没有被重绘/重建
现在我认为它可能没有任何意义,因为图 block 大小可能在更新期间发生变化,并且无论如何都需要重建 ListView ,但我的问题是:
如果 setState() 调用正常进行并且图 block 被标记为脏,那么究竟是什么阻止图 block 被重建/重绘?
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "This is the title of the App",
home: RandomWords(),
);
}
}
class RandomWordsState extends State<RandomWords> {
final List<WordPair> _suggestions = <WordPair>[];
final Set<WordPair> _saved = Set<WordPair>();
@override
Widget build(BuildContext context) {
print("dupa scaffold");
return new Scaffold(
appBar: AppBar(
title: Text('Startup Name Generator'),
),
body: _buildSuggestions(),
);
}
Widget _buildSuggestions() {
print("dupa listview");
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (BuildContext _context, int i) {
if (i.isOdd) {
return new Divider();
}
final int index = i ~/ 2;
if (index >= _suggestions.length) {
_suggestions.addAll(generateWordPairs().take(10));
}
return _buildRow(_suggestions[index]);
},
);
}
Widget _buildRow(WordPair wordPair) {
print ("build row");
return MyListTile(wordPair, _saved.contains(wordPair), () {
print("$wordPair is saved ${_saved.contains(wordPair)}");
final isSaved = _saved.contains(wordPair);
isSaved ? _saved.remove(wordPair) : _saved.add(wordPair);
});
}
}
class MyListTile extends StatefulWidget {
final MyListTileState _state;
MyListTile(WordPair wordPair, bool isSaved, Function stateChangeOnTap):
_state = MyListTileState(wordPair, isSaved, stateChangeOnTap);
@override
State<StatefulWidget> createState() => _state;
}
class RandomWords extends StatefulWidget {
@override
RandomWordsState createState() => new RandomWordsState();
}
class MyListTileState extends State<MyListTile> {
final TextStyle _biggerFont = const TextStyle(fontSize: 18.0);
WordPair wordPair;
bool isSaved;
Function stateChangeOnTap;
MyListTileState(this.wordPair, this.isSaved, this.stateChangeOnTap);
@override
Widget build(BuildContext context) {
// TODO: implement build
return new ListTile(
title: Text(
wordPair.asPascalCase,
style: _biggerFont,
),
trailing: new Icon(
isSaved ? Icons.favorite : Icons.favorite_border,
color: isSaved ? Colors.red : null,
),
onTap: () {
setState(stateChangeOnTap);
},
);
}
}
最佳答案
在此示例中,您将选定的图 block 保存在 _saved
中,因此它会更改整个 RandomWordsState
。但如果你不需要这样的东西 - 你可以避免刷新整个列表
关于android - 在 Flutter ListView 中只重建一行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53814242/