Home > Software design >  Flutter - How to connect void to build widget?
Flutter - How to connect void to build widget?

Time:04-07

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(),
        ),
      ),
    );
  }
}
  • Related