faku
faku

Reputation: 441

Updating data in Flutter

I just started learning Dart and Flutter and for starting, I would like to develop an application that acts as a server (to which we send messages from telnet).

So at the moment, I have the two following classes:

class HomeScreen extends StatefulWidget {
    @override
    _HomeScreenState createState() => new _HomeScreenState();
}

 

 class _HomeScreenState extends State<HomeScreen> {
    List<String> _messages = <String>[];

    ...
}

So as I said, the app will run as a server. I want to update the list _messages every time the server receives a message.

I would like to update it from another class, let's call it Server, from which I call i.e. HomeScreen.addMessage(String message) and I would also like to keep _HomeScreenState private.

I've searched a lot of time for a solution but didn't find anything suitable for my needs.

Could you guys help me?

Many thanks in advance!

Upvotes: 1

Views: 5038

Answers (1)

Collin Jackson
Collin Jackson

Reputation: 116708

You can have your State subscribe to a Stream of messages.

screenshot

import 'dart:async';
import 'package:flutter/material.dart';

class Server {
  StreamController<String> _controller = new StreamController.broadcast();
  void simulateMessage(String message) {
    _controller.add(message);
  }
  Stream get messages => _controller.stream;
}

final server = new Server();

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => new _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  List<String> _messages = <String>[];
  StreamSubscription<String> _subscription;

  @override
  void initState() {
    _subscription = server.messages.listen((String message) {
      setState(() {
        _messages.add(message);
      });
    });
    super.initState();
  }

  @override
  void dispose() {
    _subscription.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    TextStyle textStyle = Theme.of(context).textTheme.display2;
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Telnet Example'),
      ),
      body: new ListView(
        children: _messages.map((String message) {
          return new Card(
            child: new Container(
              height: 100.0,
              child: new Center(
                child: new Text(message, style: textStyle),
              ),
            ),
          );
        }).toList(),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.add),
        onPressed: () {
          // simulate a message arriving
          server.simulateMessage('Hello Dayrona!');
        },
      ),
    );
  }
}

class TelnetSample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData.dark(),
      home: new HomeScreen(),
    );
  }
}

void main() {
  runApp(new TelnetSample());
}

Note: You can have the List of messages be owned by the Server class if you want to make it persist even if the user visits other screens. You'll still need a Stream or other notification callback to let your the State know the list has been changed.

Upvotes: 4

Related Questions