#flutter #dart #flutter-animation
#flutter #dart #flutter-анимация
Вопрос:
Я создаю шахматные часы в flutter. когда я меняю длительность часов на странице настроек, я хочу запросить у пользователя подтверждение с помощью диалогового окна оповещения. Я хочу, чтобы диалоговое окно оповещения отображалось только на главной странице прямо сейчас, оно появляется сразу после изменения продолжительности на странице настроек.
Я использую провайдера для управления состоянием, когда я меняю продолжительность, я меняю значение bool на true. затем на домашней странице я проверяю, имеет ли значение bool значение true, а затем запускаю код диалогового окна оповещения. Я попытался ввести код диалогового future delay.Zero
окна, но это не сработало.
прямо сейчас домашняя страница перестраивается сразу после изменения настроек, и появляется диалоговое окно оповещения.
мой код:
// home page code
class HomePage extends StatefulWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with TickerProviderStateMixin, WidgetsBindingObserver {
// code for initstate and logic
late AnimationController _whiteControl;
late AnimationController _blackControl;
int whiteTime = 1;
int blackTime = 1;
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addObserver(this);
_whiteControl = AnimationController(
vsync: this,
duration: Duration(seconds: whiteTime * 60),
);
_blackControl = AnimationController(
vsync: this,
duration: Duration(seconds: blackTime * 60),
);
@override
void dispose() {
WidgetsBinding.instance!.removeObserver(this);
_whiteControl.dispose();
_blackControl.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
var gameState = Provider.of<GameState>(context, listen: false);
final ChoiceDialog resetChoice = ChoiceDialog(
buttonOkOnPressed: () {
_blackControl.reset();
_whiteControl.reset();
gameState.isgameChanged = false;
Navigator.pop(context);
},
buttonCancelOnPressed: () {
gameState.isgameChanged = false;
Navigator.pop(context);
},
);
if (gameState.isGameStarted amp;amp; gameState.isgameChanged) {
Future.delayed(Duration.zero, () {
print('👉 Game Changed ');
resetChoice.show(context);
});
}
print('🏠 Rebuilding Home Page ---');
return Scaffold();
//reset of homepage code
Код страницы настроек:
class SettingsPage extends StatelessWidget {
const SettingsPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Settings'),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: gamesList.length,
itemBuilder: (context, index) {
return Consumer<GameState>(
builder: (context, _gameState, child) {
return GestureDetector(
onTap: () {
_gameState.changeGame(gamesList[index]);
},
child: Container(),
);
},
);
}),
)
],
),
);
}
}
Логика состояния поставщика:
class Game {
final String name;
final int whiteTime;
final int blackTime;
Game({
required this.name,
required this.whiteTime,
required this.blackTime,
});
}
class GameState with ChangeNotifier {
bool turnWhite = false;
bool turnBlack = false;
bool isgameChanged = false;
bool isClocksFinished = false;
bool isPaused = false;
bool isGameStarted = false;
bool resetGame = false;
int white = 0;
int black = 0;
Game _currentGame = gamesList[0];
Game get currentGame => _currentGame;
bool get isWhiteTurn => turnWhite;
void resetGameClocks() {
resetGame = true;
notifyListeners();
}
void setTurnWhite() {
turnWhite = true;
turnBlack = false;
isGameStarted = true;
notifyListeners();
}
void setTurnBlack() {
turnWhite = false;
turnBlack = true;
isGameStarted = true;
notifyListeners();
}
void changeGame(Game game) {
_currentGame = game;
isgameChanged = true;
white = game.whiteTime;
black = game.blackTime;
notifyListeners();
}
}
репозиторий проекта: https://github.dev/tonydavidx/chess-clock-app/tree/dev
Ответ №1:
Я проверил ваш код, вы допустили ошибку в самой начальной точке / начальной точке экрана домашней страницы, пожалуйста, избегайте этого
никогда не инициализируйте и не помещайте свой код перед возвратом в функцию сборки виджетов, если вам действительно нужна какая-то логика или код, который нужно выполнить в начале, затем поместите его внутрь initstate()
или внутри вашего конструктора провайдера и обработайте его должным образом.
это основная причина проблемы, с которой вы столкнулись.
Комментарии:
1. Я инициализировал контроллеры анимации в
initstate
том, что когда я хочу сбросить длительность, я проверяю, выполняется ли определенное условие при каждой сборке страницы, и запускаю диалоговое окно предупреждения о сбросе кода. пожалуйста, проверьте мой репозиторий проекта: github.dev/tonydavidx/chess-clock-app /tree/dev2. поместите логику кода сброса внутрь a
initstate
и правильно управляйте состоянием, вся проблема в вашей технике управления состоянием или в более коротком состоянии протекает 😉