Full boilerplate project for Flutter.
Do you need another boilerplate?
- Localization
- Provider package
- Asset-related settings (Image, Icon, Color)
- Testing settings
# dependencies
cupertino_icons: ^1.0.5
intl: ^0.17.0
flutter_dotenv: ^5.0.2
logger: ^1.1.0
http: ^0.13.5
freezed_annotation: ^2.2.0
json_annotation: ^4.7.0
image_picker: ^0.8.6
shared_preferences: ^2.0.15
go_router: ^6.0.3
flutter_hooks: ^0.18.5+1
hooks_riverpod: ^2.1.3
sqflite: ^2.2.4+1
path: ^1.8.2
permission_handler: ^10.2.0
flat_list: ^0.1.13
# dev_dependencies
flutter_lints: ^2.0.1
test: ^1.22.0
mockito: ^5.3.2
build_runner: ^2.3.3
flutter_native_splash: ^2.2.16
change_app_package_name: ^1.1.0
freezed: ^2.3.2
json_serializable: ^6.5.4
flutter pub get
You have to create an .env file.
Copy an .env.example file and create an .env file.
cp .env.example .env
flutter run
This project consists of github hooks using lefthooks
Current flutter version used is written in CI.
Update riverpod provider with below command
flutter pub run build_runner watch -d
GoRouter routerConfig([String? initialLocation]) => GoRouter(
navigatorKey: _rootNavigatorKey,
initialLocation: initialLocation ?? GoRoutes.authSwitch.fullPath,
routes: <RouteBase>[
GoRoute(
name: GoRoutes.authSwitch.name,
path: GoRoutes.authSwitch.fullPath,
builder: (context, state) {
return const AuthSwitch();
},
),
GoRoute(
name: GoRoutes.home.name,
path: GoRoutes.home.fullPath,
builder: (context, state) {
return const Home();
},
),
GoRoute(
name: GoRoutes.signIn.name,
path: GoRoutes.signIn.fullPath,
builder: (context, state) {
return const SignIn();
},
),
GoRoute(
name: GoRoutes.editProfile.name,
path: GoRoutes.editProfile.fullPath,
builder: (context, state) {
var args = state.extra as EditProfileArguments;
return EditProfile(
title: args.title,
person: args.person,
);
},
),
GoRoute(
name: GoRoutes.sample.name,
path: GoRoutes.sample.fullPath,
builder: (context, state) {
return const Sample();
},
),
GoRoute(
name: GoRoutes.result.name,
path: GoRoutes.result.fullPath,
builder: (context, state) {
return const Result();
},
),
],
);
context.push(GoRoutes.sample.fullPath);
context.go(GoRoutes.sample.fullPath);
context.pop(GoRoutes.sample.fullPath);
onTap: () => context.pop(true)
onTap: () {
final bool? result = await context.push<bool>('/page2');
if(result ?? false)...
}
final Future<Database> database = openDatabase(
join(await getDatabasesPath(), 'item_database.db'),
onCreate: (db, version) {
// 데이터베이스에 CREATE TABLE 수행
return db.execute(
'CREATE TABLE item(id INTEGER PRIMARY KEY ,title TEXT, content TEXT)',
);
},
version: 1,
);
db.insert('item', item.toJson(),
conflictAlgorithm: ConflictAlgorithm.replace);
final List<Map<String, dynamic>> maps = await db.query('item');
return List.generate(maps.length, (i) {
return ItemModel(
id: maps[i]['id'],
title: maps[i]['title'],
content: maps[i]['content'],
);
});
db.delete(
'item',
where: 'id = ?',
whereArgs: [id],
);
db.update(
'item',
item.toJson(),
where: 'id = ?',
whereArgs: [item.id],
);
flutter pub add permission_handler
Add permission to your Info.plist file.
Add permissions to your AndroidManifest.xml file.
var status = await Permission.camera.status;
if (status.granted) {
/// you can do something if granted
}
if (status.isDenied) {
/// you can do something if isDenied
}
if (status == PermissionStatus.permanentlyDenied) {
/// If permanently denied, have to openAppSettings()
await openAppSettings();
}
if (await Permission.location.isRestricted) {
}
The repository is localizing using the arb recommended on the official Flutter website.
To use it, you need to install the Flutter Intl extension in your VSCode or Android studio.
You can go to the link below for installation.
When Flutter Intl is installed, a dart file is automatically created when modifying the arb file.
For posture information on this, check the document on the download link. For Korean users, you can check it on this link.
import 'package:intl/intl.dart';
...
Text(Intl.message('appName'));
or
import 'package:flutter_seoul/generated/l10n.dart';
...
Text(S.of(context).appName);
or
import 'package:flutter_seoul/utils/localization.dart'
localization(context).appName;
The following related things are called Assets.
- Images
- Icons
- Fonts
Things related to assets are created under the
res
folder.
└── res
├── icons
│ └── logo.png
├── images
│ └── logo.png
└── fonts // <- If you want, you have to make it here yourself.
To use the image or icon, you can use it as below.
import 'package:flutter_seoul/utils/asset.dart' as asset;
...
Image(
image: asset.Images.logo,
)
This project has a flutter_dotenv installed.
Enter the environmental variable you want in the .env
file as follows.
FOO=foo
BAR=bar
FOOBAR=$FOO$BAR
ESCAPED_DOLLAR_SIGN='$1000'
# This is a comment
import 'package:flutter_dotenv/flutter_dotenv.dart';
dotenv.get('FOO');
This project has a logger installed
logger.d('Log message with 2 methods');
logger.i('Info message');
logger.w('Just a warning!');
logger.e('Error! Something bad happened');
This project has a flutter_native_splash package installed. This makes it possible to show the native splash screen. Please refer to this link for instructions on how to use it.
Lastly, freezed package is used in the boilerplate.
After creating the model, you need to run the below command to generate and sync the data structure.
flutter pub run build_runner build --delete-conflicting-outputs
If using vscode, you can download extension for auto build.
In current boilerplate, user.dart
file is created and below code is written.
import "package:freezed_annotation/freezed_annotation.dart";
part "user.freezed.dart";
part "user.g.dart";
@freezed
class User with _$User {
const factory User({
required String displayName,
required int age,
required String organization,
}) = _User;
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}
Running flutter pub run build_runner build --delete-conflicting-outputs
, will generate b60b3d5.