The title:
of AppBar
is Text.
If the Body has ListView
that was made out of Stream.
How can the Text in the title reflect the ListView
number of items.
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),
)
}
)
)
}
CodePudding user response:
You can take help from addPostFrameCallback
and update the count. I am using counterStream for this example.
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();
}
},
),
);
}
}
CodePudding user response:
I implemented my suggestion by using Yeasin Sheikh's sample code.
Because stream generator make a int value in sample code,
I used 'snapshot.requiredData' instead of '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(),
);
}
},
);
}
}
CodePudding user response:
You can add addPostFrameCallback to count your data items and then use totalItem in Appbar.
build(BuildContext context) {
return Scaffold(
appBar:AppBar(title: generateTitle())
body: StreamBuilder(
stream: theStream();
builder:(BuildContext context, AsyncSnapshot<List<AnObject>> snapshot) {
if (snapshot.data.length > 0) {
SchedulerBinding.instance
.addPostFrameCallback((_) => setState(() {
totalItem = snapshot.data.length;
}));
}
return ListView.builder(
itemCount: snapshot.requireData.length,
itemBuilder: (context, index) =>
CardFromAnObject(snapshot,snapshot.requireData[index], context),
);
}
));}