我喜欢Flutter,但是我遇到了性能问题。考虑以下简单示例:
import 'package:flutter/material.dart';
void main() => runApp(MyHomePage());
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
static const elements = [
'Element 1',
'Element 2',
'Element 3',
'Element 4',
'Element 5',
'Element 6',
'Element 7',
'Element 8',
'Element 9',
'Element 10'
];
String selectedElement = elements[0];
double listViewHeight = 200;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Simple test')),
body: Column(
children: <Widget>[
Slider(
value: listViewHeight,
min: 100,
max: 300,
onChanged: (double newValue) => setState(() => listViewHeight = newValue),
),
Text('Selected: ' + selectedElement),
Container(
height: listViewHeight,
child: ListView(
children: elements
.map((id) => Element(
id: id,
color: id == selectedElement ? Colors.green : Colors.lightGreen,
onTap: (newElement) => setState(() => selectedElement = newElement),
))
.toList(),
),
),
],
),
),
);
}
}
class Element extends StatelessWidget {
final String id;
final Color color;
final Function onTap;
Element({this.id, this.color, this.onTap});
@override
Widget build(context) {
print('Building ' + id);
return GestureDetector(
onTap: () => onTap(id),
child: Container(
height: 100,
margin: EdgeInsets.all(2),
alignment: Alignment.center,
color: color,
child: Text(id),
),
);
}
}
这很好用,当我使用滑块调整列表视图的大小时,一切都变得流畅。我在现实世界中的例子要复杂得多。列表视图中的每个子视图都是另一个(水平)列表视图,其中的子视图包含小的SVG图像。在列表视图内部滚动时,一切都很流畅,但是在调整外部列表视图本身的大小时,它变得非常跳跃。
我意识到在调整列表视图大小时,所有(可见)列表视图子级都会一直重建。我的第一个想法是:这很有道理。当事情发生变化时,Flutter会重建一切。然后我意识到,滚动列表视图本身时,不会重建这些子项(除非将另一个子项滚动到视图中)。
这就像列表视图在说:“我不需要仅因为滚动位置改变而重建子代。我只需将它们移动即可。”很有道理。
现在我的问题当然是,我该怎么做?就像:“移动滑块时,我不需要重建列表视图。我只是调整当前列表视图的大小而无需重建它。