I am trying to get a new historyTile()
to be called to the Scaffold()
each second. I am unsure how to make the void function connect.
Any advice and feedback is appreciated!
Code:
class activityTab extends StatefulWidget {
const activityTab({Key? key}) : super(key: key);
@override
State<activityTab> createState() => _activityTabState();
}
class _activityTabState extends State<activityTab> {
@override
void historyTile() {
final now = DateTime.now();
String tileTime = DateFormat.yMMMMd().add_jm().format(now);
ListView.builder(
shrinkWrap: true,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.backup_outlined),
title: Text('Synced my_script.pdf with the cloud.'),
subtitle: Text('${tileTime}'),
tileColor: Colors.greenAccent,
);
}
);
}
@override
void initState() {
super.initState();
Timer.periodic(Duration(seconds: 1), (Timer t) => historyTile());
}
@override
Widget build(BuildContext context) {
return Scaffold(
body:
Container(
child: SingleChildScrollView(
child: historyTile(); // ERROR HERE
),
),
);
}
}
CodePudding user response:
You can try creating periodic streams with a Stream Builder widget. If not, the simplest method is to put your widget in scaffold and try calling the setState function periodically with a 1-second timer.
In the StreamBuilder example you should change the widget a bit. Sending the parameter you want to update to the widget from outside will add a little more flexibility to you.
return Scaffold(
body: StreamBuilder<String>(
stream: Stream.periodic(const Duration(seconds: 1), (x) {
// Your Action Here
final now = DateTime.now();
return DateFormat.yMMMMd().add_jm().format(now);
}),
builder: (context, snapshot) {
String param = "";
if (snapshot.hasData) param = snapshot.data!;
return _historyTile(txt = param);
}
),
);
Or you could use your widget in Scaffold Body and periodically set the widgets state in timer callback.
class _activityTabState extends State<activityTab> {
String tileTime = "";
...
Timer.periodic(Duration(seconds: 1), () {
setState(() {
final now = DateTime.now();
tileTime = DateFormat.yMMMMd().add_jm().format(now);
});
};
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SingleChildScrollView(
child: historyTile(tileName);
),
),
);
}
or just
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: SingleChildScrollView(
child: ListTile(
leading: Icon(Icons.backup_outlined),
title: Text('Synced my_script.pdf with the cloud.'),
subtitle: Text('$tileTime'),
tileColor: Colors.greenAccent,
),
),
),
);
}
Create your historyTile widget as a custom widget
class HistoryTile extends StatefulWidget {
const HistoryTile({Key? key, required this.txt}) : super(key: key);
final String txt;
@override
State<HistoryTile> createState() => _HistoryTileState();
}
class _HistoryTileState extends State<HistoryTile> {
@override
Widget build(BuildContext context) {
return ListTile(
leading: Icon(Icons.backup_outlined),
title: Text('Synced my_script.pdf with the cloud.'),
subtitle: Text(widget.txt),
tileColor: Colors.greenAccent,
);
}
}
CodePudding user response:
there is some issues in you ListView.Builder
. You do not put itemCount
there. And you need to use setState
in timer. So codes are below. Please check.
class activityTab extends StatefulWidget {
const activityTab({Key? key}) : super(key: key);
@override
State<activityTab> createState() => _activityTabState();
}
class _activityTabState extends State<activityTab> {
String _now;
Timer _everySecond;
@override
historyTile() {
final now = DateTime.now();
String tileTime = DateFormat.yMMMMd().add_jms().format(now);
return ListView.builder(
shrinkWrap: true,
itemCount: 1,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.backup_outlined),
title: Text('Synced my_script.pdf with the cloud.'),
subtitle: Text('${tileTime}'),
tileColor: Colors.greenAccent,
);
});
}
void _timer() {
Future.delayed(Duration(seconds: 1)).then((_) {
setState(() {
_timer();
});
});
}
@override
void initState() {
super.initState();
_timer();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: 500,
child: SingleChildScrollView(
child: historyTile(),
),
),
);
}
}