应用栏和 ListView.length
AppBar and ListView.length
AppBar
的 title:
是文本。
如果 Body 有 ListView
是由 Stream 制作的。
标题中的文本如何反映ListView
项数。
build(BuildContext context) {
return Scaffold(
appBar:AppBar(title: generateTitle()) // <-- how to pass the snapshot.requiredData.length into here?
body: StreamBuilder(
stream: theStream();
builder:(BuildContext context, AsyncSnapshot<List<AnObject>> snapshot) {
return ListView.builder(
itemCount: snapshot.requireData.length,
itemBuilder: (context, index) =>
CardFromAnObject(snapshot,snapshot.requireData[index], context),
)
}
)
)
}
您可以向 addPostFrameCallback
寻求帮助并更新计数。我在这个例子中使用了 counterStream。
class _TSCState extends State<TSC> {
var counterStream =
Stream<int>.periodic(const Duration(seconds: 1), (x) => x).take(15);
int? itemsCount;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: itemsCount != null
? Text("total $itemsCount")
: Text("loading") // null // or use others expression
),
body: StreamBuilder<int>(
stream: counterStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
setState(() {
itemsCount = snapshot.data!;
});
});
return ListView.builder(
itemCount: snapshot.data!,
itemBuilder: (context, index) => ListTile(
title: Text("Item $index"),
),
);
} else {
//handle others state
return CircularProgressIndicator();
}
},
),
);
}
}
我使用 Yeasin Sheikh 的示例代码实现了我的建议。
因为流生成器在示例代码中生成了一个int值,
我用 'snapshot.requiredData' 而不是 'snapshot.requiredData.length'.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: TSCState(),
);
}
}
class TSCState extends StatefulWidget {
TSCState({Key key}) : super(key: key);
@override
_TSCStateState createState() => _TSCStateState();
}
class _TSCStateState extends State<TSCState> {
var counterStream =
Stream<int>.periodic(const Duration(seconds: 1), (x) => x).take(15);
int itemsCount;
@override
Widget build(BuildContext context) {
return StreamBuilder<int>(
stream: counterStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Scaffold(
appBar: AppBar(
title: Text("total ${snapshot.requireData}"),
),
body: ListView.builder(
itemCount: snapshot.data,
itemBuilder: (context, index) => ListTile(
title: Text("Item $index"),
),
),
);
} else {
return Scaffold(
appBar: AppBar(title: Text("total")),
body: CircularProgressIndicator(),
);
}
},
);
}
}
您可以添加addPostFrameCallback来统计您的数据项,然后在Appbar中使用totalItem。
build(BuildContext context) {
return Scaffold(
appBar:AppBar(title: generateTitle())
body: StreamBuilder(
stream: theStream();
builder:(BuildContext context, AsyncSnapshot<List<AnObject>> snapshot) {
if (latchRefresher != snapshot.requireData.length){//init the field on declare to latchRefresher =-1
SchedulerBinding.instance
.addPostFrameCallback((_) => setState(() {
totalItem = snapshot.data.length;
latchRefresher = snapshot.requireData.length;//this will cause only on change to request a refresh
}));
}
return ListView.builder(
itemCount: snapshot.requireData.length,
itemBuilder: (context, index) =>
CardFromAnObject(snapshot,snapshot.requireData[index], context),
);
}
));}
您可以使用另一个 StreamBuilder 包装 AppBar 标题 属性,然后在流“theStream”结束时更新它。
我上传了关于这个要点的示例代码:https://gist.github.com/Alvarocda/140bbafb7eb24441ba9612a8ccf068ad
基本上,虽然 _appBarCountStreamController 在流上具有空值,但您的应用栏将显示 'Loading'。
当您的流 'theStream' 运行时,您将列表的长度添加到 __appBarCountStreamController,它将仅重建应用栏标题。
不要忘记在 dispose 方法上关闭 _appBarCountStreamController。
AppBar
的 title:
是文本。
如果 Body 有 ListView
是由 Stream 制作的。
标题中的文本如何反映ListView
项数。
build(BuildContext context) {
return Scaffold(
appBar:AppBar(title: generateTitle()) // <-- how to pass the snapshot.requiredData.length into here?
body: StreamBuilder(
stream: theStream();
builder:(BuildContext context, AsyncSnapshot<List<AnObject>> snapshot) {
return ListView.builder(
itemCount: snapshot.requireData.length,
itemBuilder: (context, index) =>
CardFromAnObject(snapshot,snapshot.requireData[index], context),
)
}
)
)
}
您可以向 addPostFrameCallback
寻求帮助并更新计数。我在这个例子中使用了 counterStream。
class _TSCState extends State<TSC> {
var counterStream =
Stream<int>.periodic(const Duration(seconds: 1), (x) => x).take(15);
int? itemsCount;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: itemsCount != null
? Text("total $itemsCount")
: Text("loading") // null // or use others expression
),
body: StreamBuilder<int>(
stream: counterStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
WidgetsBinding.instance!.addPostFrameCallback((timeStamp) {
setState(() {
itemsCount = snapshot.data!;
});
});
return ListView.builder(
itemCount: snapshot.data!,
itemBuilder: (context, index) => ListTile(
title: Text("Item $index"),
),
);
} else {
//handle others state
return CircularProgressIndicator();
}
},
),
);
}
}
我使用 Yeasin Sheikh 的示例代码实现了我的建议。
因为流生成器在示例代码中生成了一个int值,
我用 'snapshot.requiredData' 而不是 'snapshot.requiredData.length'.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: TSCState(),
);
}
}
class TSCState extends StatefulWidget {
TSCState({Key key}) : super(key: key);
@override
_TSCStateState createState() => _TSCStateState();
}
class _TSCStateState extends State<TSCState> {
var counterStream =
Stream<int>.periodic(const Duration(seconds: 1), (x) => x).take(15);
int itemsCount;
@override
Widget build(BuildContext context) {
return StreamBuilder<int>(
stream: counterStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Scaffold(
appBar: AppBar(
title: Text("total ${snapshot.requireData}"),
),
body: ListView.builder(
itemCount: snapshot.data,
itemBuilder: (context, index) => ListTile(
title: Text("Item $index"),
),
),
);
} else {
return Scaffold(
appBar: AppBar(title: Text("total")),
body: CircularProgressIndicator(),
);
}
},
);
}
}
您可以添加addPostFrameCallback来统计您的数据项,然后在Appbar中使用totalItem。
build(BuildContext context) {
return Scaffold(
appBar:AppBar(title: generateTitle())
body: StreamBuilder(
stream: theStream();
builder:(BuildContext context, AsyncSnapshot<List<AnObject>> snapshot) {
if (latchRefresher != snapshot.requireData.length){//init the field on declare to latchRefresher =-1
SchedulerBinding.instance
.addPostFrameCallback((_) => setState(() {
totalItem = snapshot.data.length;
latchRefresher = snapshot.requireData.length;//this will cause only on change to request a refresh
}));
}
return ListView.builder(
itemCount: snapshot.requireData.length,
itemBuilder: (context, index) =>
CardFromAnObject(snapshot,snapshot.requireData[index], context),
);
}
));}
您可以使用另一个 StreamBuilder 包装 AppBar 标题 属性,然后在流“theStream”结束时更新它。
我上传了关于这个要点的示例代码:https://gist.github.com/Alvarocda/140bbafb7eb24441ba9612a8ccf068ad
基本上,虽然 _appBarCountStreamController 在流上具有空值,但您的应用栏将显示 'Loading'。
当您的流 'theStream' 运行时,您将列表的长度添加到 __appBarCountStreamController,它将仅重建应用栏标题。
不要忘记在 dispose 方法上关闭 _appBarCountStreamController。