Flutter 颤振:SliverPersistentHeader在卷轴上重建自身
我已经为我遇到的这个问题构建了一个小的测试示例。您可以从下面的gif中看到,Flatter应用程序的顶部只有一个标题。当我下拉刷新时,标题不会自行重建。但是,当我向上推收割台时,收割台会多次自我重建。还要注意的是,我没有在代码中的任何地方调用setState(),因此我不确定当我向上推scrollview时,它如何知道需要重建自身 我不想重建自己,因为没有理由它应该重建自己。它是静态/无状态的,根本不应该更改。收割台的尺寸也不应改变(因此展开高度和收拢高度在136.0处相同) 下面是我为您重新创建的示例代码:Flutter 颤振:SliverPersistentHeader在卷轴上重建自身,flutter,Flutter,我已经为我遇到的这个问题构建了一个小的测试示例。您可以从下面的gif中看到,Flatter应用程序的顶部只有一个标题。当我下拉刷新时,标题不会自行重建。但是,当我向上推收割台时,收割台会多次自我重建。还要注意的是,我没有在代码中的任何地方调用setState(),因此我不确定当我向上推scrollview时,它如何知道需要重建自身 我不想重建自己,因为没有理由它应该重建自己。它是静态/无状态的,根本不应该更改。收割台的尺寸也不应改变(因此展开高度和收拢高度在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)),
]),
));
}
}
import'package:meta/meta.dart';
进口“包装:颤振/材料.省道”;
进口“包装:颤振/cupertino.dart”;
导入'dart:math'作为数学;
导入“dart:async”;
类_TestHeader扩展SliverPersistentHeaderDelegate{
_测试头({
@需要此。折叠高度,
@需要此。展开高度,
@需要此。显示标题,
});
bool-showtheding;
最终双膨胀高度;
最终双折高度;
@凌驾
double get minExtent=>collapsedHeight;
@凌驾
double-get-maxExtent=>math.max(expandedHeight,minExtent);
@凌驾
小部件构建(
BuildContext上下文、双收缩偏移、布尔重叠内容){
打印(“重建标题”);
返回新的安全区域(
子项:列(子项:[
const SizedBox(高度:24.0),
新手势检测器(
onTap:(){
},
子容器:新容器(
装饰:康斯特盒子装饰(
颜色:铜色。白色,
边界:康斯特边界(
顶部:常量边界边(颜色:常量颜色(0xFFBCBBC1),宽度:0.0),
底部:
常量边界边(颜色:常量颜色(0xFFBCBBC1),宽度:0.0),
),
),
身高:44.0,
孩子:新的填充物(
衬垫:
常数边集对称(水平:16.0,垂直:8.0),
儿童:新安全区(
上图:错,
底部:错误,
孩子:新的一排(
mainAxisAlignment:mainAxisAlignment.center,
儿童:康斯特[
常量文本(
“这是我的标题”,
样式:const TextStyle(颜色:CupertinoColors.activeBlue,fontSize:16.0),
)
],
),
),
),
),
),
]));
}
@凌驾
bool shouldRebuild(@checked\u TestHeader oldDelegate){
//返回false;
返回expandedHeight!=oldDelegate.expandedHeight||
collapsedHeight!=oldDelegate.collapsedHeight;
}
}
类TestHeaderPage扩展StatefulWidget{
@凌驾
状态createState(){
//TODO:实现createState
返回新的TestHeaderState();
}
}
类TestHeaderState扩展状态{
@凌驾
小部件构建(构建上下文){
//TODO:实现构建
返回新的CupertinoPageScaffold(
//我需要将其转换为一个小片段列表,以使其正常工作。
背景颜色:常量颜色(0xFFEFFF4),
导航栏:新的CupertinaVigationBar(
中间:新文本(“测试标题”),
),
儿童:新安全区(
子项:新的CustomScrollView(片段:[
新的CupertinoRefreshControl(onRefresh:(){
打印(“刷新时拉动”);
返回未来((){});
}),
新型滑片导板(
代表:新的_TestHeader(
折叠高度:136.0,
扩展高度:136.0,
showtheading:true),
]),
));
}
}
这是完全正常的
您的\u TestHeader
不是小部件。仅仅因为它有build
方法并不意味着它就是一个。:)
您扩展了用于构建SliverPersistentHeaderDelegate
的SliverPersistentHeaderDelegate
问题是:SliverPersistentHeader
也不是小部件。它是一条细条,这是一种在屏幕上渲染东西的不同方式
而且,在SliverPersistentHeader
的情况下,它是一种特定类型的sliver,每当滚动偏移量改变时都会重新生成。也就是说,可以处理特定于滚动的动画。
例如向上滚动使标题消失。并向下滚动,使其快速回复 谢谢你的解释。我还注意到,我需要提供折叠和扩展高度的标题,但我只需要一个静态标题。如果我不提供折叠和扩展的高度,没有silver可以只渲染静态标题(固定的标题,大小不会改变)吗?您不需要将它们传递给\u TestHeader
。您可以将它们从构造函数中删除,并将它们从harcodeminExtent
和maxExtent
中删除到136.0