AppBar重新设置动画时(滚动条到达顶部之后),SliverAppBar无法显示内容。
在下面包括一个示例项目来演示该问题。复制/粘贴下面的代码(将rxdart依赖项添加到pubspec.yaml中)并运行app。请注意,SliverAppBar包含一些来自流的文本(请参见下面的功能1和2)。现在向下滚动计数器列表,直到SliverAppBar消失。滚动备份以使AppBar重新显示,请注意现在有两个ProgressIndicators但没有文本。
要求一旦AppBar再次出现在视图中即可显示文本,理想情况下不必再次调用以下功能(这些实际上是实际应用中的api调用):
SliverAppBar内容功能
bloc.fetchTestAppBarTxt1();
bloc.fetchTestAppBarTxt2();
示例应用
void main() => runApp(TestApp());
class TestApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
TestBloc bloc = TestBloc();
bloc.fetchTestTimeline();
bloc.fetchTestAppBarTxt1();
bloc.fetchTestAppBarTxt2();
return MaterialApp(
home: new Scaffold(
backgroundColor: Colors.grey[200],
appBar: AppBar(
backgroundColor: Colors.blueGrey,
elevation: 0.0,
),
body: CustomScrollView(slivers: <Widget>[
SliverAppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.grey[400],
expandedHeight: 200.0,
floating: true,
snap: true,
flexibleSpace: FlexibleSpaceBar(
background: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 2.0),
height: 200,
child: Column(
children: <Widget>[
StreamBuilder(
stream: bloc.testAppBarTxt1,
initialData: null,
builder: (BuildContext context,
AsyncSnapshot<String> snapshot) {
if (snapshot.data == null)
return buildProgressIndicator(true);
return Expanded(
child: Text('${snapshot.data}'));
}),
StreamBuilder(
stream: bloc.testAppBarTxt2,
initialData: null,
builder: (BuildContext context,
AsyncSnapshot<String> snapshot) {
if (snapshot.data == null)
return buildProgressIndicator(true);
return Expanded(
child: Text('${snapshot.data}'));
}),
],
),
)
],
),
)),
timelineList(bloc)
])),
);
}
Widget timelineList(TestBloc bloc) {
return StreamBuilder(
stream: bloc.getTestTimeline,
initialData: null,
builder: (BuildContext context, AsyncSnapshot<List<int>> snapshot) {
List<int> val = snapshot.data;
if (val == null)
return SliverToBoxAdapter(child: buildProgressIndicator(true));
if (val.isNotEmpty) {
addToTimelineList(val, bloc);
return SliverList(
delegate: SliverChildListDelegate(new List<Widget>.generate(
bloc.listTest.length, (int index) {
if (index == bloc.listTest.length) {
return SliverToBoxAdapter(
child: buildProgressIndicator(bloc.isPerformingRequest));
} else {
return bloc.listTest[index];
}
})
));
}
});
}
void addToTimelineList(List<int> list, TestBloc bloc) {
for (var val in list) {
bloc.listTest.add(Text('$val'));
}
}
}
class TestBloc {
List<Text> listTest = new List<Text>();
bool isPerformingRequest = false;
final _testAppBarText1 = PublishSubject<String>();
Observable<String> get testAppBarTxt1 => _testAppBarText1.stream;
final _testAppBarText2 = PublishSubject<String>();
Observable<String> get testAppBarTxt2 => _testAppBarText2.stream;
final _testTimeline = PublishSubject<List<int>>();
Observable<List<int>> get getTestTimeline => _testTimeline.stream;
fetchTestTimeline() async {
List item = await Future.delayed(
Duration(seconds: 2), () => List<int>.generate(100, (i) => i));
_testTimeline.sink.add(item);
}
fetchTestAppBarTxt1() async {
String val = await Future.delayed(Duration(seconds: 2), () => "Text One");
_testAppBarText1.sink.add(val);
}
fetchTestAppBarTxt2() async {
String val = await Future.delayed(Duration(seconds: 2), () => "Text Two");
_testAppBarText2.sink.add(val);
}
dispose() {
_testAppBarText1.close();
_testAppBarText2.close();
_testTimeline.close();
}
}
答案 0 :(得分:0)
这是因为每次您再次隐藏并显示小部件时,内部的StreamBuilder都会等待数据,而您没有使用initialData。
要修复您的代码,您将必须使用BehaviorSubject
和ValueObservable
,请检查以下修复程序:
final _testAppBarText1 = BehaviorSubject<String>();
ValueObservable<String> get testAppBarTxt1 => _testAppBarText1.stream;
final _testAppBarText2 = BehaviorSubject<String>();
ValueObservable<String> get testAppBarTxt2 => _testAppBarText2.stream;
StreamBuilder(
stream: bloc.testAppBarTxt1,
initialData: bloc.testAppBarTxt1.value,
StreamBuilder(
stream: bloc.testAppBarTxt2,
initialData: bloc.testAppBarTxt2.value,