0

In following code, there's a Greetings list, a Text widget and a 'Refresh' Elevated button. The entire app is a Stateful widget. I want the Text to change to the next greeting from the User list, when the user clicks the Refresh button.

However, when I run it, the Text doesn't change. All that happens is that the 'We have more greetings' text gets printed in the terminal.

Please help if you know how to resolve this!

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  var _greetingsIndex = 0;
  var _greetings = [
    "Hey, how are you!",
    "Trust you're fine, my friend!",
    "What's up!!!",
    "How are you doing!",
  ];

  void _refreshGreetings() {
    setState(() {
      _greetingsIndex = _greetingsIndex + 1;
    });
    if (_greetingsIndex < _greetings.length) {
      print('We have more greetings');
    } else {
      setState(() {
        _greetingsIndex = 0;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(
            title: Text('Greetings app'),
          ),
          body: Column(
            children: [
              Text(_greetings[0]),
              ElevatedButton(
                  onPressed: _refreshGreetings, child: Text('Refresh'))
            ],
          ),
        ));
  }
}
Ajith R
  • 3
  • 2
  • Thanks everyone. Changing _greetings[0] to _greetings[_greetingsIndex] worked! Note: When I moved the first setState method to inside the if statement, I was getting a range error. – Ajith R Mar 28 '21 at 13:48

3 Answers3

0

You have a typo - you always show greeting with index 0. Instead of:

body: Column(
            children: [
              Text(_greetings[0]),
              ElevatedButton(
                  onPressed: _refreshGreetings, child: Text('Refresh'))
            ],
          )

Use

body: Column(
            children: [

              // this line needed fixing
              Text(_greetings[_greetingsIndex]),

              ElevatedButton(
                  onPressed: _refreshGreetings, child: Text('Refresh'))
            ],
          )
Andrija
  • 1,534
  • 3
  • 10
0

it is not changing because you are specifically asking for the first element of the list. the state is changing and the index is changing just fine, but you are asking for _greetings[0] in your code. change Text(_greetings[0]) to Text(_greetings[_greetingsIndex]) and it should work just fine.

by the way, this code will break when reaching the end of the list because you are rebuilding before checking the length. i suggest moving this piece

setState(() {
  _greetingsIndex = _greetingsIndex + 1;
});

to the inside of the if statement, then your _refreshGreetings function should look like this:

void _refreshGreetings() {
  if (_greetingsIndex < _greetings.length) {
    print('We have more greetings');
    setState(() {
      _greetingsIndex = _greetingsIndex + 1;
    });
  }
}
Adnan
  • 906
  • 13
  • 30
0

Change this Text(_greetings[0]) to this => Text(_greetings[_greetingsIndex]).

and your refresh function to this:

void _refreshGreetings() {
    if (_greetingsIndex < _greetings.length) {
    setState(() {
      _greetingsIndex = _greetingsIndex + 1;
    });
      print('We have more greetings');
    } else {
      setState(() {
        _greetingsIndex = 0;
      });
    }
  }

It should solve your problem.

Huthaifa Muayyad
  • 11,321
  • 3
  • 17
  • 49