massivefermion
massivefermion

Reputation: 675

How to refresh a route page

I followed the startup name generator tutorial in the flutter website and there was no problem. But then I wanted to add the ability to remove wordpairs from the saved list. That worked too but when a word was removed from the list, the listview wouldn't update and I had to go back to the main page and open the list again to see the effect. I searched for a way to update the listview at the setState function that I delete the wordpair in, but I could't find anything. So after removing the wordpair in the setstate, I just popped the route and pushed it again. Can anyone suggest a better way? Thanks

Upvotes: 2

Views: 3439

Answers (3)

massivefermion
massivefermion

Reputation: 675

I fixed it by making the list of saved pairs a separate stateful widget. I knew this would make the list refresh each time I deleted a pair but I thought the link between the states of the two stateful widgets would be lost and any time I deleted a pair from the list of saved pairs, the favorite icon in the other stateful widget would not update. But amazingly I was wrong. The states are somehow connected. I assume its because they're two stateful widgets on the same stack. I'm beginning to really like flutter.

Upvotes: 2

Ringil
Ringil

Reputation: 6537

Assuming you've just used the main.dart from the startup name generator tutorial, then you can just modify your _buildRow function to add a delete button which will then call setState and modify the _suggestions list like this:

Widget _buildRow(WordPair pair) {
    return ListTile(
        title: Text(
          pair.asPascalCase,
          style: _biggerFont,
        ),
        subtitle: RaisedButton(
            child: Text('delete'),
            onPressed: () {
              setState(() {
                _suggestions.remove(pair);
              });
            }));
  }

And here's the full main.dart:

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Startup Name Generator',
      home: RandomWords(),
    );
  }
}

class RandomWordsState extends State<RandomWords> {
  final _suggestions = <WordPair>[];

  final _biggerFont = const TextStyle(fontSize: 18.0);

  Widget _buildSuggestions() {
    return ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemBuilder: (context, i) {
          // Add a one-pixel-high divider widget before each row in theListView.
          if (i.isOdd) return Divider();

          final index = i ~/ 2;
          if (index >= _suggestions.length) {
            _suggestions.addAll(generateWordPairs().take(10));
          }
          return _buildRow(_suggestions[index]);
        });
  }

  Widget _buildRow(WordPair pair) {
    return ListTile(
        title: Text(
          pair.asPascalCase,
          style: _biggerFont,
        ),
        subtitle: RaisedButton(
            child: Text('delete'),
            onPressed: () {
              setState(() {
                _suggestions.remove(pair);
              });
            }));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Startup Name Generator'),
      ),
      body: _buildSuggestions(),
    );
  }
}

class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => new RandomWordsState();
}

Upvotes: 0

Zeusox
Zeusox

Reputation: 8448

You might be able to do that using a StreamBuilder. Using that, your argument should like the following:

stream: FirebaseDatabase.instance.reference().child(
      "profiles").onValue

As you can see, the onValue will automatically update your screen whenever you delete a value.

Upvotes: 0

Related Questions