Reputation: 475
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?
Upvotes: 4
Views: 1927
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
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
Reputation: 1636
Two mistakes:
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);
}
_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