我为我遇到的这个问题建立了一个小测试示例。您可以从下面的gif看到,Flutter应用程序顶部只有一个标题。当我下拉刷新时,标题不会重建。但是,当我向上推动标题时,标题会重建多次。另请注意,我没有在我的代码中的任何地方调用setState(),因此当我向上推滚动视图时,我不确定它是如何知道它需要重建自身。
我想首先不重建自己,因为没有理由重建自己。它是静态/无状态的,根本不应该改变。标题的大小也应该不会改变(因此,expandHeight和collapsedHeight在136.0处相同)。
以下是我用来重新创建的示例代码:
import 'package:meta/meta.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:math' as math;
import 'dart:async';
class _TestHeader extends SliverPersistentHeaderDelegate {
_TestHeader({
@required this.collapsedHeight,
@required this.expandedHeight,
@required this.showHeading,
});
bool showHeading;
final double expandedHeight;
final double collapsedHeight;
@override
double get minExtent => collapsedHeight;
@override
double get maxExtent => math.max(expandedHeight, minExtent);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
print("rebuilding headings");
return new SafeArea(
child: Column(children: <Widget>[
const SizedBox(height: 24.0),
new GestureDetector(
onTap: () {
},
child: new Container(
decoration: const BoxDecoration(
color: CupertinoColors.white,
border: const Border(
top: const BorderSide(color: const Color(0xFFBCBBC1), width: 0.0),
bottom:
const BorderSide(color: const Color(0xFFBCBBC1), width: 0.0),
),
),
height: 44.0,
child: new Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
child: new SafeArea(
top: false,
bottom: false,
child: new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const <Widget>[
const Text(
'This is my heading',
style: const TextStyle(color: CupertinoColors.activeBlue, fontSize: 16.0),
)
],
),
),
),
),
),
]));
}
@override
bool shouldRebuild(@checked _TestHeader oldDelegate) {
// return false;
return expandedHeight != oldDelegate.expandedHeight ||
collapsedHeight != oldDelegate.collapsedHeight;
}
}
class TestHeaderPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return new TestHeaderState();
}
}
class TestHeaderState extends State<TestHeaderPage> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new CupertinoPageScaffold(
//i will need to convert this to a sliver list to make this work properly.
backgroundColor: const Color(0xFFEFEFF4),
navigationBar: new CupertinoNavigationBar(
middle: new Text('Test Headers'),
),
child: new SafeArea(
child: new CustomScrollView(slivers: <Widget>[
new CupertinoRefreshControl(onRefresh: () {
print("pulling on refresh");
return Future<void>(() {});
}),
new SliverPersistentHeader(
delegate: new _TestHeader(
collapsedHeight: 136.0,
expandedHeight: 136.0,
showHeading: true)),
]),
));
}
}
答案 0 :(得分:3)
这是完全正常的。
您的_TestHeader
不小部件。仅仅因为它具有build
方法并不意味着它是一个。 :)
您扩展了SliverPersistentHeaderDelegate
,用于构建SliverPersistentHeader
。
事情是:SliverPersistentHeader
不小部件。这是一个条子,这是一种在屏幕上呈现内容的不同方式。
而且,在SliverPersistentHeader
的情况下,只要滚动偏移发生变化,它就会重建一种特定的条子。也就是说,可能处理滚动特定的动画。
如向上滚动使标题消失。然后向下滚动以使其快速恢复。