I have a simple app that has a OnBoarding section and at the end I just want to replace the current screen with the home.
I have installed this package to avoid to recreate myself the onboarding logic and seems to work well, but can't figured out why at the end when I implement the onDone
function it shows me the same screen.
Here my main.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sizer/sizer.dart';
// Application
import './theme.dart';
import './routes.dart';
import './screens/home/home.dart';
import './screens/onboarding/onboarding.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
bool shoudShowOnboardingPage =
sharedPreferences.getBool('shoudShowOnboardingPage') ?? true;
runApp(
MyApp(
shouldShowOnBoardingScreen: shoudShowOnboardingPage,
),
);
}
class MyApp extends StatelessWidget {
final bool shouldShowOnBoardingScreen;
MyApp({
this.shouldShowOnBoardingScreen,
});
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return OrientationBuilder(
builder: (context, orientation) {
SizerUtil().init(constraints, orientation);
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'My app',
theme: themeData,
home: shouldShowOnBoardingScreen
? OnBoardingScreen()
: HomePageScreen(),
onGenerateRoute: RouteGenerator.generateRoute,
);
},
);
});
}
}
Here my routes.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// Application
import './screens/home/home.dart';
import './screens/onboarding/onboarding.dart';
class RouteGenerator {
static const String homePage = '/';
static const String onBoardingPage = '/onboarding';
RouteGenerator._();
static Route<dynamic> generateRoute(RouteSettings settings) {
switch (settings.name) {
case homePage:
return MaterialPageRoute(
builder: (_) => HomePageScreen(),
);
case onBoardingPage:
return MaterialPageRoute(
builder: (_) => OnBoardingScreen(),
);
default:
throw FormatException('Route not found');
}
}
}
My onBoarding (the repository just define title, body and image for the pages):
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:introduction_screen/introduction_screen.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sizer/sizer.dart';
// Application
import '../../repositories/onboarding/onboarding_repository.dart';
import '../../models/onboarding/onboarding_page.dart';
import '../../routes.dart';
class OnBoardingScreen extends StatelessWidget {
final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
@override
Widget build(BuildContext context) {
OnBoardingRepository onBoardingRepository = OnBoardingRepository();
return Scaffold(
body: IntroductionScreen(
globalBackgroundColor: Colors.black,
pages: List.generate(
onBoardingRepository.pages.length,
(index) =>
buildPageViewModel(onBoardingRepository.pages[index], context),
),
showSkipButton: true,
skip: Text(
'Salta',
style: TextStyle(
color: Colors.white,
),
),
next: const Icon(
Icons.arrow_forward,
color: Colors.white,
),
done: Container(
padding: const EdgeInsets.symmetric(
horizontal: 20,
vertical: 6,
),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
border: Border.all(
color: Theme.of(context).primaryColor,
),
borderRadius: BorderRadius.all(
Radius.circular(20),
),
),
child: Text(
'Fine',
style: TextStyle(
color: Colors.white,
),
),
),
onDone: () async {
final SharedPreferences sharedPreferences = await _prefs;
sharedPreferences.setBool('shoudShowOnboardingPage', false).then((_) {
Navigator.of(context).pushReplacementNamed(RouteGenerator.homePage);
});
},
dotsDecorator: DotsDecorator(
activeColor: Theme.of(context).primaryColor,
size: const Size.square(10.0),
activeSize: const Size(20.0, 10.0),
color: Colors.white,
spacing: const EdgeInsets.symmetric(horizontal: 3.0),
activeShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0),
),
),
),
);
}
PageViewModel buildPageViewModel(
OnBoardingPage onBoardingPage, BuildContext context) {
return PageViewModel(
title: onBoardingPage.title,
body: onBoardingPage.body,
image: Padding(
padding: EdgeInsets.only(top: 10.0.h),
child: Center(
child: SvgPicture.asset(
onBoardingPage.image,
height: 60.0.w,
),
),
),
decoration: PageDecoration(
titleTextStyle: TextStyle(
fontSize: 16.0.sp,
fontWeight: FontWeight.w700,
color: Theme.of(context).primaryColor,
),
bodyTextStyle: TextStyle(fontSize: 13.0.sp, color: Colors.white),
),
);
}
}
And here the home.dart
import 'package:flutter/material.dart';
class HomePageScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('hello'),
),
);
}
}
The onboarding section works well, I can see the pages, navigate them. The problem is when I press the done
button and invoke the onDone
function it shows again and again the onboarding screen from the beginning.
What I expect is to remove the onBoarding screen and replace it with the home just after I set the boolean value for my shoudShowOnboardingPage
setting.
Here the piece of code that do not work as I expect:
onDone: () async {
final SharedPreferences sharedPreferences = await _prefs;
sharedPreferences.setBool('shoudShowOnboardingPage', false).then((_) {
Navigator.of(context).pushReplacementNamed(RouteGenerator.homePage);
});
},
What am I missing?
question from:
https://stackoverflow.com/questions/65888174/flutter-navigator-pushreplacementnamed-show-the-same-page