Pamela
Pamela

Reputation: 475

Text not showing in stateful widget on Flutter

I'm trying to create a very simple app where an element from a list gets displayed when the center widget is clicked.

This is my code:

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

void main() => runApp(
      MaterialApp(home: MyApp()),
    );

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(),
      ),
    );
  }
}

class picker extends StatefulWidget {
  @override
  _pickerState createState() => _pickerState();
}

class _pickerState extends State<picker> {
  List yourList = ["Yes", "No", "Maybe"];
  int randomIndex;

  _pickerState() {
    int randomIndex = Random().nextInt(yourList.length);
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextButton(
        onPressed: () {
          setState(() {
            print(yourList[randomIndex]);
          });
        },
        child: Text('$randomIndex'),
      ),
    );
  }
}

There are no errors shown but at the same time, my objective isn't reached since no text is shown, and nothing is printed in the terminal even if I've added this code print(yourList[randomIndex]);. How do I display the text and make the print appear?

enter image description here

Upvotes: 4

Views: 1927

Answers (3)

user13315601
user13315601

Reputation:

Another solution is to set

randomIndex = Random().nextInt(yourList.length);

in setState(() { like below.

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

void main() => runApp(
      MaterialApp(home: MyApp()),
    );

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        backgroundColor: Colors.white,
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: picker(),
      ),
    );
  }
}

class picker extends StatefulWidget {
  @override
  _pickerState createState() => _pickerState();
}

class _pickerState extends State<picker> {
  List yourList = ["Yes", "No", "Maybe"];
  int randomIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: TextButton(
        onPressed: () {
          setState(() {
            randomIndex = Random().nextInt(yourList.length);
          });
        },
        child: Text(yourList[randomIndex]),
      ),
    );
  }
}

To have a starting text the setState needs to be taken out in a separate function like:

class _pickerState extends State<picker> {
 List yourList = ["Yes", "No", "Maybe"];
 String buttonText = "Initial Text";
 int randomIndex = 0;
 
 void _newRandomIndex() {
   setState(() {
     randomIndex = Random().nextInt(yourList.length);
     buttonText = yourList[randomIndex];
   });
 }

 @override
 Widget build(BuildContext context) {
   return Center(
     child: TextButton(
       onPressed: _newRandomIndex,
       child: Text(buttonText),
     ),
   );
 }
}

Upvotes: 2

Harry
Harry

Reputation: 644

Try using this.randomIndex = Random().nextInt(yourList.length); instead when initializing a variable in a constructor body.

Otherwise, you are declaring a different local variable when the class is initialized.

Next time try debugging this error by setting a default value outside of initialization to check if there is a similar problem such as your initialization not going through to your state.

I'd also suggest that you change your class names to CamelCase to avoid confusion and so people can see that that is code for when the class initializes. Here is a dart article on styling code.

Upvotes: 0

Hamza
Hamza

Reputation: 1636

Two mistakes:

  1. You were not assigning value to the variable you actually wanted to use here:
  int randomIndex;

  _pickerState() {
    // you declared a local variable here and you were using value of variable you declared on top
    int randomIndex = Random().nextInt(yourList.length);
  }
  1. The method _pickerState() was not called and that's why there was null value in the TextButton.

Here's the working code, you can simply copy paste it:

class _PickerState extends State<Picker> {
  List yourList = ["Yes", "No", "Maybe"];
  int randomIndex;

  _pickerState() {
    randomIndex = Random().nextInt(yourList.length);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextButton(
          onPressed: () {
            _pickerState();
            setState(() {
              print(yourList[randomIndex]);
            });
          },
          child: Text('$randomIndex'),
        ),
      ),
    );
  }
}

Quick Tip: Try to use UpperCase for naming the class or any CustomWidget its more convenient way

Upvotes: 1

Related Questions