Seed Application for Flutter
This is a Seed Application which helps any Flutter Dev team to create a Flutter app (Android, iOS, Web, Windows, and Linux) from scratch that includes the following features:
- Left Navigation Nodes.
- App Bar, Bottom Toolbar, Slider Controls.
- Push Notifications.
- Authentications (Face ID and Fingerprint).
- Build controls like Button, TextField with custom styling.
Steps:
1. Create a Flutter App:
flutter create AppName
2. To Run the base app:
flutter run
3. To Import this package:
flutter pub add app_sprout
4. Replace main.dart code:
Widget build(BuildContext context) {
return MaterialApp(
home: SplashScreen(
nextScreen: HomeScreen(),
imagePath: 'assets/logo.png',
),
);
}
}
class HomeScreen extends StatelessWidget {
HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(child: Text('Welcome to Home Screen')),
);
}
}
5. Splash Screen Set up:
Create folder assets and add logo.png. Add the below line in pubspec.yaml:
assets:
- assets/logo.png
6. App Bar Set up:
Create folder assets and add logo.png. Add the below line in pubspec.yaml:
appBar: AppBar(
title: const Text('Whats New!'),
)
7. Left Drawer Set up:
List<DrawerItem> drawerItems = [
DrawerItem(title: 'Activity'),
DrawerItem(title: 'Account')
];
final toolbarItems = [
Toolbar(
label: 'new',
),
Toolbar(label: 'notification'),
];
drawer: DrawerWidget(
drawerItems: drawerItems,
onTapFunction: (context, identifier) {}),
8. Right Drawer Set up:
endDrawer: RightDrawer(
drawerItems: drawerItems,
onTapFunction: (context, identifier) {}),
9. Bottom Toolbar Set up:
bottomNavigationBar: BottomToolbar(
items: toolbarItems,
onTapFunction: (context, identifier) {},
),
10. Push Notification Set up:
void initState() {
super.initState();
try {
NotificationServices notificationServices = NotificationServices();
notificationServices.requestNotificationPermission();
notificationServices.firebaseInit(context);
notificationServices.setupInteractMessage(context);
final globalData = Provider.of<GlobalData>(context, listen: false);
notificationServices.getDeviceToken().then((value) {
if (value == "invalid") {
const snackBar = SnackBar(
content: Text('token is invalid'),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
} else {
globalData.setDeviceId(value);
print('device token is : $value');
}
});
} catch (e) {
print('issue getting token: $e');
}
}
11. Authentication Complete Code:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:local_auth/local_auth.dart';
import 'package:pinaka/components/new.dart';
import 'package:pinaka/components/notification.dart';
class AuthenticateScreen extends StatefulWidget {
const AuthenticateScreen({super.key});
@override
State<AuthenticateScreen> createState() => AuthenticateScreenState();
}
class AuthenticateScreenState extends State<AuthenticateScreen> {
late final LocalAuthentication auth;
bool _supportState = false;
bool _isAuthenticated = false;
final toolbarItems = [
Toolbar(identifier: 'new', label: 'new', icon: 'activity'),
Toolbar(
identifier: 'notification',
label: 'notification',
icon: 'appointments'),
];
final List<DrawerItem> drawerItems = [
DrawerItem(
iconPath: 'assets/icons/activity.svg', title: 'new', identifier: 'new'),
DrawerItem(
iconPath: 'assets/icons/appointments.svg',
title: 'notification',
identifier: 'notification'),
];
@override
void initState() {
super.initState();
auth = LocalAuthentication();
auth.isDeviceSupported().then(
(bool isSupported) => setState(() {
_supportState = isSupported;
}),
);
}
void onTapFunction(BuildContext context, String identifier) {
if (routes.containsKey(identifier)) {
Navigator.of(context).push(
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 500),
pageBuilder: (context, animation, secondaryAnimation) {
return SlideTransition(
position: Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: routes[identifier]!,
);
},
),
);
}
Scaffold.of(context).closeEndDrawer();
}
final Map<String, Widget> routes = {
'new': const NewScreen(),
'notification': const NotificationScreen(),
'authenticate': const AuthenticateScreen(),
};
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Authentication'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (_supportState)
const Text('This device is supported')
else
const Text('This device is not supported'),
Divider(height: 100),
ElevatedButton(
onPressed: _getAvailableBioMetrics,
child: const Text('Get Available BioMetrics'),
),
Divider(height: 100),
ElevatedButton(
onPressed: _authenticate,
child: const Text('Authenticate'),
),
Divider(height: 50),
if (_isAuthenticated)
const Text('Authenticated')
else
const Text('Not Authenticated'),
],
),
);
}
Future<void> _getAvailableBioMetrics() async {
List<BiometricType> availableBioMetrics = await auth.getAvailableBiometrics();
print(availableBioMetrics);
if (!mounted) {
return;
}
}
Future<void> _authenticate() async {
try {
bool authenticated = await auth.authenticate(
localizedReason: 'Authenticate',
options: const AuthenticationOptions(
stickyAuth: true, biometricOnly: false));
if (authenticated)
setState(() {
_isAuthenticated = true;
});
print(authenticated);
} on PlatformException catch (e) {
print(e);
}
}
}