I'm new to Flutter/Dart and to programming as a whole. I'm fiddling around and trying to create a simple app for my golf club, just to have a 'mission'. At the moment I am really struggling to construct navigation in the app using Navigation Routes.
For my own sake and readability of the code, I have split up my code in separate files. My home page comprises of a Scaffold, which in turn holds a number of cards which 'should' lead to different pages within the app. So for this, I've created a separate dart file holding all of the cards from the main menu. My code for a card looks like this:
Widget testTapCard() => const Card(
//shadowColor: Color.fromARGB(0, 0, 0, 0),
//elevation: 1.0,
color: Color.fromRGBO(235, 238, 242, 1),
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
bottomLeft: Radius.circular(8.0),
bottomRight: Radius.circular(8.0)),
),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const testPagina()),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 5.0,
),
Icon(
Icons.touch_app_rounded,
size: 50,
color: Color(0xFF36855E),
),
SizedBox(
height: 20,
),
Text('Tap me!',
style: TextStyle(
color: Color(0xFF7C7C7C),
),
),
],
),
),
);
Using the 'onTap' function in combination with the Inkwell widget, I made my cards tappable. Now I want to use that to navigate to a certain page per card using Navigator.pushNamed.
This is my main.dart file:
import 'package:flutter/material.dart';
import 'package:golfy/pages/homepage.dart';
import 'package:flex_color_scheme/flex_color_scheme.dart';
void main() {
runApp(const MyApp(
));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: const HomePage(),
routes: {
'/testpagina':(context) => const TestPagina(),
},
// same or higher package version, but still same major version. If you
// use a lower package version, some properties may not be supported.
// In that case remove them after copying this theme to your app.
theme: FlexThemeData.light(
scheme: FlexScheme.greenM3,
surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
blendLevel: 7,
subThemesData: const FlexSubThemesData(
blendOnLevel: 10,
blendOnColors: false,
useTextTheme: true,
useM2StyleDividerInM3: true,
alignedDropdown: true,
useInputDecoratorThemeInDialogs: true,
),
visualDensity: FlexColorScheme.comfortablePlatformDensity,
useMaterial3: true,
swapLegacyOnMaterial3: true,
// To use the Playground font, add GoogleFonts package and uncomment
// fontFamily: GoogleFonts.notoSans().fontFamily,
),
darkTheme: FlexThemeData.dark(
scheme: FlexScheme.greenM3,
surfaceMode: FlexSurfaceMode.levelSurfacesLowScaffold,
blendLevel: 13,
subThemesData: const FlexSubThemesData(
blendOnLevel: 20,
useTextTheme: true,
useM2StyleDividerInM3: true,
alignedDropdown: true,
useInputDecoratorThemeInDialogs: true,
),
visualDensity: FlexColorScheme.comfortablePlatformDensity,
useMaterial3: true,
swapLegacyOnMaterial3: true,
// To use the Playground font, add GoogleFonts package and uncomment
// fontFamily: GoogleFonts.notoSans().fontFamily,
),
// If you do not have a themeMode switch, uncomment this line
// to let the device system mode control the theme mode:
// themeMode: ThemeMode.system,
);
}
}
And here's my homepage.dart file:
import 'package:flutter/material.dart';
import 'baanstatus.dart';
import 'account.dart';
import 'ledeninfo.dart';
import '/pages/Subpages/home/menucards.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int currentPageIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(
'Oosterhoutse Golf Club'),
centerTitle: true,
//leading: const Icon(Icons.menu_rounded),
elevation: 1.0,
actions: [
Container(
margin: const EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
alignment: Alignment.center,
child: const Icon(Icons.notifications_rounded)
),
]
),
bottomNavigationBar: NavigationBar(
onDestinationSelected: (int index) {
setState(() {
currentPageIndex = index;
});
},
indicatorColor: const Color(0x3D006A60),
selectedIndex: currentPageIndex,
destinations: const <Widget>[
NavigationDestination(
selectedIcon: Icon(Icons.home),
icon: Icon(Icons.home_rounded),
label: 'Home',
),
NavigationDestination (
selectedIcon: Icon(Icons.sports_golf_rounded),
icon: Icon(Icons.sports_golf_rounded),
label: 'Baanstatus',
),
NavigationDestination(
selectedIcon: Icon(Icons.info_rounded),
icon: Icon(Icons.info_rounded),
label: 'Leden Info',
),
NavigationDestination(
selectedIcon: Icon(Icons.account_circle_rounded),
icon: Icon(Icons.account_circle_rounded),
label: 'Account',
),
],
),
body: <Widget>[
/// Home Page
const HomeBody(),
/// Baanstatus Page
const BaanStatus(),
/// Kalender Page
const LedeninfoPage(),
// Profiel Page
const AccountPage(),
]
[currentPageIndex],
);
}
}
class HomeBody extends StatelessWidget {
const HomeBody({super.key});
@override
Widget build(BuildContext context) {
return buildMenuCardList();
}
}
Widget buildMenuCardList() => GridView.count(
crossAxisCount: 2,
primary: false,
padding: const EdgeInsets.all(20.0),
crossAxisSpacing: 10,
mainAxisSpacing: 10,
children: <Widget>[
teeTimeCard(),
handicartReservationCard(),
newsCard(),
competitionCard(),
playHandicapCard(),
scoreEntryCard(),
rankingCard(),
memberListCard(),
volunteerCard(),
calendarCard(),
testTapCard(),
],
);
class TestPagina extends StatefulWidget {
const TestPagina({super.key});
@override
State<TestPagina> createState() => _TestPaginaState();
}
class _TestPaginaState extends State<TestPagina> {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
const Text('Welkom op de testpagina!'),
ElevatedButton(
child: const Text('Return'),
onPressed: () {
Navigator.pop(context);
}
),
],
);
}
}
In my homepage.dart file, the last class, I have created a page that should be reached by tapping the 'testTapCard'. Currently it is build using BuildContext context, but that leads to errors. Renaming it to something else also does not help. On my homepage.dart, buildMenuCardList widget, I've added things like 'testPagina', 'TestPagina' and 'testPagina as BuildContext' but that leads to no errors in my code, but upon running the app in my iOS simulator, I get a red screen telling my that 'type of '_Type' isn't valid'.
I'm completely stuck and it really bugs me that it's probably something really simple I'm missing. I sincerely hope someone can make something of this long "article" of mine and point me in the right direction.
I FOUND IT!!!!!!!! WOOO!!!
I had to add 'BuildContext context' several times into several widgets on my homepage.dart file and everything started working... I'll write my working code here, hoping it'll help a newbie sometime in the future too. Thanks everyone for pointing me in the right direction!
First, I added a route in my main.dart file, in my Material.app, like so:
class _MyAppState extends State<MyApp> { @override Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: const HomePage(),
routes: {
'/testpagina2':(context) => const TestPagina2(),
},
Ps. my code looks more clean in VS Code, StackOverflow isn't playing nice.
I then edited my card to look like this:
Widget testTapCard2(BuildContext context) { return Card(
//shadowColor: Color.fromARGB(0, 0, 0, 0),
//elevation: 1.0,
color: const Color.fromRGBO(235, 238, 242, 1),
clipBehavior: Clip.antiAliasWithSaveLayer,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.0),
topRight: Radius.circular(8.0),
bottomLeft: Radius.circular(8.0),
bottomRight: Radius.circular(8.0)),
),
child: InkWell(
onTap: () {
Navigator.pushNamed(context, '/testpagina2');
},
child: const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 5.0,
),
Icon(
Icons.touch_app_rounded,
size: 50,
color: Color(0xFF36855E),
),
SizedBox(
height: 20,
),
Text(
'Tap me!',
style: TextStyle(
color: Color(0xFF7C7C7C),
),
),
],
)
),);}
I then added either (BuildContext context) or (context) to every widget on my homepage.dart file.