Anonymous
Flutter GoRouter не отображается при повторном открытии приложения
Сообщение
Anonymous » 07 янв 2025, 13:48
Я столкнулся со следующей проблемой:
При обычном использовании приложения, если я нажму кнопку «Назад» на корневом маршруте (/), приложение закроется. Пока что такое поведение нормально и работает так, как ожидалось. Однако, когда я снова открываю приложение, ничего не отображается. Хоть элементы и есть (так как я могу взаимодействовать с кнопками, касаясь экрана), но их не видно.
флаттер-доктор
Код: Выделить всё
[√] Flutter (Channel stable, 3.19.0, on Microsoft Windows [Version 10.0.22631.4602], locale en-US)
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.11.4)
[√] Android Studio (version 2024.1)
[√] VS Code (version 1.96.2)
[√] Connected device (4 available)
[√] Network resources
app_routes.dart
Код: Выделить всё
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../pages/pages.dart';
final appRouterProvider = Provider((ref) {
return GoRouter(
initialLocation: '/',
routes: [
GoRoute(
path: '/',
builder: (context, state) => const HomePage(),
routes: [
GoRoute(
path: 'new-game',
builder: (context, state) => const NewGamePage(),
)
],
),
],
);
});
main.dart
Код: Выделить всё
import 'package:flag_game/dependecies.dart';
// import 'package:flag_game/pages/pages.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'config/routes/route.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
const config = String.fromEnvironment('config');
String fileName = '.env';
if (config.isNotEmpty) {
fileName = '$fileName.$config';
}
await dotenv.load(fileName: 'env/$fileName');
dependecies();
runApp(const ProviderScope(child: App()));
}
class App extends ConsumerWidget {
const App({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final appRouter = ref.watch(appRouterProvider);
return MaterialApp.router(
title: 'Flag Game',
routerConfig: appRouter,
restorationScopeId: 'app',
// builder: (context, route) => Scaffold(
// body: route,
// ),
);
}
}
home_page.dart
Код: Выделить всё
// import 'package:flag_game/pages/pages.dart';
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:shared_preferences/shared_preferences.dart';
// import '../config/routes/route.dart';
class HomePage extends ConsumerStatefulWidget {
const HomePage({super.key});
@override
ConsumerState createState() => _HomePageState();
}
class _HomePageState extends ConsumerState {
int bestScore = 0;
@override
void initState() {
super.initState();
getBestScore();
}
Future sharedPreferences() async {
return await SharedPreferences.getInstance();
}
Future getBestScore() async {
final prefs = await sharedPreferences();
var score = prefs.getInt("bestScore") ?? 0;
setState(() {
bestScore = score;
});
}
@override
Widget build(BuildContext context) {
Widget title = Text(
'Mejor puntaje: $bestScore',
style: const TextStyle(
fontWeight: FontWeight.w900,
fontSize: 40,
color: Color(0xFF666870),
height: 0.9,
letterSpacing: -2,
),
);
title = title
.animate(onPlay: (controller) => controller.repeat(reverse: true))
.saturate(delay: 500.milliseconds, duration: 500.milliseconds)
.then() // set baseline time to previous effect's end time
// .tint(color: const Color(0xFF80DDFF))
.then()
.blurXY(end: 1)
.fadeOut();
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
title,
Padding(
padding: const EdgeInsets.only(top: 20),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStatePropertyAll(Colors.grey[300])),
onPressed: () {
context.push('/new-game');
},
child: const Text(
"Juego Nuevo",
style: TextStyle(color: Colors.black),
)),
),
],
)),
);
}
}
new_game_page.dart
Код: Выделить всё
import 'package:data/data.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../services/services.dart';
class NewGamePage extends ConsumerStatefulWidget {
const NewGamePage({super.key});
@override
ConsumerState createState() => _NewGamePageState();
}
class _NewGamePageState extends ConsumerState {
GameService gameService = GameService();
bool disableButtons = false;
bool loadingImg = false;
int bestScoreLocal = 0;
int bestScoreGlobal = 0;
int lives = 0;
QuestionResponseModel questionResponse = QuestionResponseModel();
@override
void initState() {
super.initState();
newGame();
}
Future sharedPreferences() async {
return await SharedPreferences.getInstance();
}
void newGame() {
setupGame();
newQuestion();
getBestScore();
}
void setupGame() {
setState(() {
lives = 5;
});
}
void gameOver() {
context.pop();
}
void newQuestion() async {
final r = await gameService.newQuestion(QuestionParamsModel());
setState(() {
questionResponse = r;
disableButtons = false;
});
}
void validateAnswer(CountryItemModel el) {
loadingImg = true;
bool isGameOver = false;
setState(() {
disableButtons = true;
});
String msg = "Correcto";
String gameOverText = "Juego Terminado";
String correctAnsw = '';
bool isCorrect = el.id == questionResponse.correctAnswer?.id;
if (!isCorrect) {
msg = "Incorrecto";
correctAnsw = questionResponse.correctAnswer!.countryName;
lives -= 1;
} else {
setState(() {
bestScoreLocal += 1;
});
}
isGameOver = lives == 0;
if (isGameOver) {
setBestScore();
}
showModalBottomSheet(
useSafeArea: true,
isDismissible: false,
barrierColor: Colors.transparent,
context: context,
builder: (BuildContext context) {
return Container(
padding: const EdgeInsets.all(10),
height: 230,
child:Placeholder(),
);
},
);
}
Future setBestScore() async {
final prefs = await sharedPreferences();
var score = prefs.getInt('bestScore') ?? 0;
if (bestScoreLocal > score) {
prefs.setInt('bestScore', bestScoreLocal);
}
}
Future getBestScore() async {
final prefs = await sharedPreferences();
var score = prefs.getInt('bestScore') ?? 0;
setState(() {
bestScoreGlobal = score;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.greenAccent,
title: const Center(child: Text("Adivina la Bandera")),
),
body: Container(
padding: const EdgeInsets.all(10),
child: Placeholder(),
));
}
}
Как показано на видео, когда я нажимаю кнопку «Назад», чтобы закрыть приложение, все выглядит нормально. Однако при повторном открытии на экране никакие элементы не отображаются. Если вы посмотрите на консоль VS Code, приложение на самом деле не завершает свое выполнение, но я не могу понять, в чем причина проблемы.
Кто-нибудь знает, что может быть? Что-то не так?
Я пробовал добавить restorationScopeId: 'app', но тщетно. Я изменил конфигурацию в основном файле, закомментировав раздел builder, но это не работает.
Подробнее здесь:
https://stackoverflow.com/questions/793 ... ng-the-app
1736246919
Anonymous
Я столкнулся со следующей проблемой: При обычном использовании приложения, если я нажму кнопку «Назад» на корневом маршруте (/), приложение закроется. Пока что такое поведение нормально и работает так, как ожидалось. Однако, когда я снова открываю приложение, ничего не отображается. Хоть элементы и есть (так как я могу взаимодействовать с кнопками, касаясь экрана), но их не видно. [b]флаттер-доктор[/b] [code][√] Flutter (Channel stable, 3.19.0, on Microsoft Windows [Version 10.0.22631.4602], locale en-US) [√] Windows Version (Installed version of Windows is version 10 or higher) [√] Android toolchain - develop for Android devices (Android SDK version 35.0.0) [√] Chrome - develop for the web [√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.11.4) [√] Android Studio (version 2024.1) [√] VS Code (version 1.96.2) [√] Connected device (4 available) [√] Network resources [/code] [b]app_routes.dart[/b] [code]import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../pages/pages.dart'; final appRouterProvider = Provider((ref) { return GoRouter( initialLocation: '/', routes: [ GoRoute( path: '/', builder: (context, state) => const HomePage(), routes: [ GoRoute( path: 'new-game', builder: (context, state) => const NewGamePage(), ) ], ), ], ); }); [/code] [b]main.dart[/b] [code]import 'package:flag_game/dependecies.dart'; // import 'package:flag_game/pages/pages.dart'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'config/routes/route.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); const config = String.fromEnvironment('config'); String fileName = '.env'; if (config.isNotEmpty) { fileName = '$fileName.$config'; } await dotenv.load(fileName: 'env/$fileName'); dependecies(); runApp(const ProviderScope(child: App())); } class App extends ConsumerWidget { const App({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final appRouter = ref.watch(appRouterProvider); return MaterialApp.router( title: 'Flag Game', routerConfig: appRouter, restorationScopeId: 'app', // builder: (context, route) => Scaffold( // body: route, // ), ); } } [/code] [b]home_page.dart[/b] [code]// import 'package:flag_game/pages/pages.dart'; import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:shared_preferences/shared_preferences.dart'; // import '../config/routes/route.dart'; class HomePage extends ConsumerStatefulWidget { const HomePage({super.key}); @override ConsumerState createState() => _HomePageState(); } class _HomePageState extends ConsumerState { int bestScore = 0; @override void initState() { super.initState(); getBestScore(); } Future sharedPreferences() async { return await SharedPreferences.getInstance(); } Future getBestScore() async { final prefs = await sharedPreferences(); var score = prefs.getInt("bestScore") ?? 0; setState(() { bestScore = score; }); } @override Widget build(BuildContext context) { Widget title = Text( 'Mejor puntaje: $bestScore', style: const TextStyle( fontWeight: FontWeight.w900, fontSize: 40, color: Color(0xFF666870), height: 0.9, letterSpacing: -2, ), ); title = title .animate(onPlay: (controller) => controller.repeat(reverse: true)) .saturate(delay: 500.milliseconds, duration: 500.milliseconds) .then() // set baseline time to previous effect's end time // .tint(color: const Color(0xFF80DDFF)) .then() .blurXY(end: 1) .fadeOut(); return Scaffold( body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ title, Padding( padding: const EdgeInsets.only(top: 20), child: ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStatePropertyAll(Colors.grey[300])), onPressed: () { context.push('/new-game'); }, child: const Text( "Juego Nuevo", style: TextStyle(color: Colors.black), )), ), ], )), ); } } [/code] [b]new_game_page.dart[/b] [code]import 'package:data/data.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../services/services.dart'; class NewGamePage extends ConsumerStatefulWidget { const NewGamePage({super.key}); @override ConsumerState createState() => _NewGamePageState(); } class _NewGamePageState extends ConsumerState { GameService gameService = GameService(); bool disableButtons = false; bool loadingImg = false; int bestScoreLocal = 0; int bestScoreGlobal = 0; int lives = 0; QuestionResponseModel questionResponse = QuestionResponseModel(); @override void initState() { super.initState(); newGame(); } Future sharedPreferences() async { return await SharedPreferences.getInstance(); } void newGame() { setupGame(); newQuestion(); getBestScore(); } void setupGame() { setState(() { lives = 5; }); } void gameOver() { context.pop(); } void newQuestion() async { final r = await gameService.newQuestion(QuestionParamsModel()); setState(() { questionResponse = r; disableButtons = false; }); } void validateAnswer(CountryItemModel el) { loadingImg = true; bool isGameOver = false; setState(() { disableButtons = true; }); String msg = "Correcto"; String gameOverText = "Juego Terminado"; String correctAnsw = ''; bool isCorrect = el.id == questionResponse.correctAnswer?.id; if (!isCorrect) { msg = "Incorrecto"; correctAnsw = questionResponse.correctAnswer!.countryName; lives -= 1; } else { setState(() { bestScoreLocal += 1; }); } isGameOver = lives == 0; if (isGameOver) { setBestScore(); } showModalBottomSheet( useSafeArea: true, isDismissible: false, barrierColor: Colors.transparent, context: context, builder: (BuildContext context) { return Container( padding: const EdgeInsets.all(10), height: 230, child:Placeholder(), ); }, ); } Future setBestScore() async { final prefs = await sharedPreferences(); var score = prefs.getInt('bestScore') ?? 0; if (bestScoreLocal > score) { prefs.setInt('bestScore', bestScoreLocal); } } Future getBestScore() async { final prefs = await sharedPreferences(); var score = prefs.getInt('bestScore') ?? 0; setState(() { bestScoreGlobal = score; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Colors.greenAccent, title: const Center(child: Text("Adivina la Bandera")), ), body: Container( padding: const EdgeInsets.all(10), child: Placeholder(), )); } } [/code] Как показано на видео, когда я нажимаю кнопку «Назад», чтобы закрыть приложение, все выглядит нормально. Однако при повторном открытии на экране никакие элементы не отображаются. Если вы посмотрите на консоль VS Code, приложение на самом деле не завершает свое выполнение, но я не могу понять, в чем причина проблемы. Кто-нибудь знает, что может быть? Что-то не так? Я пробовал добавить restorationScopeId: 'app', но тщетно. Я изменил конфигурацию в основном файле, закомментировав раздел builder, но это не работает. Подробнее здесь: [url]https://stackoverflow.com/questions/79335708/flutter-gorouter-does-not-render-when-reopening-the-app[/url]