#flutter #dart
#флаттер #dart
Вопрос:
Я пытаюсь создать очень простое приложение, в котором элемент из списка отображается при нажатии на центральный виджет.
Это мой код:
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'),
),
);
}
}
Ошибок не отображается, но в то же время моя цель не достигнута, поскольку текст не отображается, и в терминале ничего не печатается, даже если я добавил этот код print(yourList[randomIndex]);. Как мне отобразить текст и отобразить печать?
Комментарии:
1. я не вижу, куда вы переходите от класса MyApp к средству выбора классов? Если вы просто поместите Center() в тело класса MyApp, он никогда не изменится, поскольку он никуда не перемещается
Ответ №1:
Другим решением является установка
randomIndex = Random().nextInt(yourList.length);
в setState(() { как показано ниже.
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]),
),
);
}
}
Чтобы иметь начальный текст, setState необходимо вывести в отдельной функции, например:
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),
),
);
}
}
Комментарии:
1. Спасибо! Лучший ответ когда-либо. Кстати, вы знаете, как запускать рандомизацию только при нажатии? Можно ли инициализировать центральный текст моим собственным пользовательским текстом, например, «Спросить что-нибудь», и при нажатии на него будут отображаться только да, нет или, возможно, появляются.
Ответ №2:
Две ошибки:
- Вы не присваивали значение тому
variable
, которое вы на самом деле хотели использовать здесь:
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()
не был вызван, и именно поэтомуnull
вTextButton
.
Вот рабочий код, вы можете просто скопировать и вставить его:
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'),
),
),
);
}
}
Быстрый совет: попробуйте использовать UpperCase
для именования class
или любой CustomWidget
его более удобный способ
Ответ №3:
Попробуйте использовать this.randomIndex = Random().nextInt(yourList.length);
вместо этого при инициализации переменной в теле конструктора.
В противном случае вы объявляете другую локальную переменную при инициализации класса.
В следующий раз попробуйте отладить эту ошибку, установив значение по умолчанию вне инициализации, чтобы проверить, есть ли аналогичная проблема, например, ваша инициализация не проходит в ваше состояние.
Я бы также посоветовал вам изменить имена ваших классов на camelCase, чтобы избежать путаницы и чтобы люди могли видеть, что это код для инициализации класса. Вот статья dart о стилизации кода.