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:

  1. Left Navigation Nodes.
  2. App Bar, Bottom Toolbar, Slider Controls.
  3. Push Notifications.
  4. Authentications (Face ID and Fingerprint).
  5. 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);
    }
  }
}