If you starting a brand new app with Flutter - the auto-generated code is not usefull at all.
So I would show you how to create a more-or-less starter-ready app structure with some components each app should have nowadays.
Those components are 'localization' and 'Theme Provider'. We also make use of MaterialYou Navigation Bar and Tabs.
I am not going to make a details description of everything, it's pretty intuitive and the docu of single modules could be find on their github-pages
You can find the source code here: https://github.com/quadriq/flutter-starter-kit
Let's start
run to add those packages to pubspec.yaml
flutter pub add easy_localization
flutter pub add theme_provider
edit pubspec.yaml
and adduncomment assets settings
# To add assets to your application, add an assets section, like this:
assets:
- assets/i18n/
so now we are ready.. delete everything in lib
folder and add those filestructure
lib/
main.dart
utils
v.dart
views/
app/
main_screen.dart
home/
home_tab.dart
settings
settings_tab.dart
Settings and Globals
we store them in utils/v.dart
class V {
static const String VERSION = '0.0.1';
static const String THEME_LIGHT = 'light';
static const String THEME_DARK = 'dark';
}
Localizations
for usage of localizations first create a en.json
file in assets/i18n
folder. We would fill this with some translations. We would also use only english in our example.
{
"app_name": "Starter App",
"tab_home": "Home",
"tab_settings": "Settings",
"text_home": "Home",
"text_settings": "Settings"
}
Coding
main.dart
contains initialization of locales, themes, and calls the main App-View class MainScreen
import 'package:ballfoot/utils/v.dart';
import 'package:ballfoot/views/app/main_screen.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:theme_provider/theme_provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(
EasyLocalization(
supportedLocales: [
Locale('en')
],
fallbackLocale: Locale('en'),
path: 'assets/i18n',
child: MyApp()
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ThemeProvider(
saveThemesOnChange: true,
loadThemeOnInit: false,
onInitCallback: (controller, previouslySavedThemeFuture) async {
String? savedTheme = await previouslySavedThemeFuture;
if (savedTheme != null) {
print("DEBUG_ load saved theme");
controller.setTheme(savedTheme);
} else {
print("DEBUG_ load new theme");
Brightness platformBrightness =
SchedulerBinding.instance.window.platformBrightness;
if (platformBrightness == Brightness.dark) {
controller.setTheme(V.THEME_DARK);
} else {
controller.setTheme(V.THEME_LIGHT);
}
controller.forgetSavedTheme();
}
},
themes: <AppTheme>[
AppTheme.dark(id: 'dark'),
AppTheme.light(id: 'light'),
],
child: ThemeConsumer(
child: Builder(
builder: (themeContext) => MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeProvider.themeOf(themeContext).data,
home: MainScreen(themeId: ThemeProvider.themeOf(themeContext).id),
locale: context.locale,
supportedLocales: context.supportedLocales,
localizationsDelegates: context.localizationDelegates,
),
),
),
);
}
}
Navigation Bar
MainScreen
is our main view class. Here how we make usage of NAvigationBar with some color adjustments:
bottomNavigationBar: NavigationBarTheme(
data: NavigationBarThemeData(indicatorColor: Colors.red),
child: NavigationBar(
onDestinationSelected: (index) =>
setState(() => _tabSelectedIndex = index),
selectedIndex: _tabSelectedIndex,
destinations: [
NavigationDestination(
icon: Icon(Icons.home), label: tr('tab_home')),
NavigationDestination(
icon: Icon(Icons.settings), label: tr('tab_settings')),
],
),
)
and how we change between Dark/Light mode
_changeTheme(){
var controller = ThemeProvider.controllerOf(context);
if(ThemeProvider.themeOf(context).id == V.THEME_LIGHT){
controller.setTheme(V.THEME_DARK);
_themeIcon = Icons.dark_mode;
} else {
controller.setTheme(V.THEME_LIGHT);
_themeIcon = Icons.light_mode;
}
}