My app has a BottomNavigationBar
with two BottomNavigationBarItem
: HomePage()
and UserPage()
.
main()
runs App()
and App()
returns FutureBuilder
to handle flutter initialization error and loading gif. Then it returns MaterialApp
with first page being AuthPage()
or Navigation()
depending on the user login status. Navigation()
has the BottomNavigationBar
.
This is my flutter inspector diagram.
As you can see, I have two pages (HomePage()
and UserPage()
) in my navigation but only HomePage()
is shown in my inspector.
Real problem is that Theme.of(context).textTheme.headline1
works in HomePage()
but not in UserPage()
. My ThemeData
is specified in MaterialApp
. Why can't I track context and retrieve ThemeData
from UserPage()
?
I haven't tried yet but chances are that Theme.of(context).textTheme.headline1
won't work in AuthPage()
either.
Code is below.
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(App());
}
class App extends StatelessWidget {
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initialization,
builder: (context, snapshot) {
if(snapshot.connectionState != ConnectionState.done) {
return LoadingGif();
} else if(snapshot.hasError) {
print(snapshot.error);
return ErrorPage(context);
}
return MaterialApp(
title: 'My App',
theme: theme, //ThemeData theme is defined in another file
home: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Navigation();
} else {
return AuthPage();
}
},
),
routes: {
'auth': (context) => AuthPage(),
'home': (context) => Navigation(),
},
);
},
);
}
}
class Navigation extends StatefulWidget {
const Navigation({Key? key}) : super(key: key);
@override
_NavigationState createState() => _NavigationState();
}
class _NavigationState extends State<Navigation> {
int _selectedIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: _widgetOptions.elementAt(_selectedIndex),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
label: 'Home',
icon: Icon(Icons.home_outlined, size: 36)
),
BottomNavigationBarItem(
label: 'My Page',
icon: Icon(Icons.account_circle_outlined, size: 36)
)
],
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
},
),
);
}
List _widgetOptions = [
HomePage(),
UserPage()
];
}
This is UserPage()
.
class UserPage extends StatelessWidget {
UserPage({Key? key}) : super(key: key);
UserProfileHandler _userProfileHandler = new UserProfileHandler();
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Scaffold(
appBar: TopBar(
pageTitle: '내 정보',
actionList: <Widget>[
IconButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => SettingsPage()));
},
icon: Icon(Icons.settings),
)
]
),
body: SingleChildScrollView(
child: Column(
children: [
UserTapBody(),
Divider(),
]
),
)
);
}
Widget UserTapBody() {
return StreamBuilder(
stream: _userProfileHandler.userProfileStream(),
builder: (context, snapshot) {
//error, loading
if (snapshot.hasError) {
print(snapshot.error);
return Center(child: ErrorPage(context));
} else if (snapshot.connectionState == ConnectionState.waiting) {
return LoadingGif();
}
UserProfile userProfile = snapshot.data as UserProfile;
return DefaultTabController(
length: 3, // length of tabs
initialIndex: 0,
child: ListView(
shrinkWrap: true,
children: <Widget>[
const TabBar(
labelColor: brandColor,
labelStyle: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold
),
indicatorColor: brandColor,
unselectedLabelColor: Colors.black,
unselectedLabelStyle: TextStyle(fontWeight: FontWeight.normal),
tabs: [
Tab(text: '회원 정보'),
Tab(text: '만남 내역'),
Tab(text: '멘토 정보'),
],
),
Container(
height: 500, //height of TabBarView
child: TabBarView(
children: <Widget>[
UserDetail(context, userProfile),
Container(
child: Center(
child: Text('만남 내역', style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold)),
),
),
Container(
child: Center(
child: Text('멘토 정보', style: TextStyle(
fontSize: 22, fontWeight: FontWeight.bold)),
),
),
]
)
)
]
)
);
}
);
}
Widget UserDetail(context, userProfile) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
children: [ // These are the ones that Theme.of(context) doesn't work
Text('자기소개', style: Theme.of(context).textTheme.caption),
Spacer(),
EditTextButton(context: context, editPage: editIntro(userProfile: userProfile))
],
),
Html(data: userProfile.intro ?? ""),
Text('이력 및 경험', style: Theme.of(context).textTheme.caption,),
Html(data: userProfile.exp ?? ""),
Text('저서', style: Theme.of(context).textTheme.caption,),
Html(data: userProfile.pub ?? ""),
]
),
);
}
}