Flutter Jetpack is a Collection of Abstract Class, useful to handle the state of a flutter application with low boiler code unlike BLOC, Provider, River Pod State management Patterns. Let's check an example implementing Flutter Jetpack.
Key Features
- LiveData : It works as a State holder and Change notifier.
- As a State holder, it holds the current value.
- As a Change notifier, it updates and reads the current values and can notify the user. Which can Further pass to EventQueue.
- EventQueue : It holds the temporary Events like Toasts/pop-up for showing the updates in the App within the ViewModel and discards after Completing.
- ViewModel : It Contains the Business Logic code ,which manages Whole Flow. Means From Updating Current Value in LiveData , Showing Pop-up/Toast using EventQueue ,Updating the Actual Value (For Eg: in Database).
Example: In a Social Media App, When a user Posting Content on His Profile.
- LiveData Holds the data and update the value.
- EventQueue Shows Toast like “Successfully Posted” after it posted.
- ViewModel manages the whole flow from hold the user data to updating that data in his profile.
Steps Implementing Flutter Jetpack
Step 1: Create a new flutter application
We can create new flutter application directly using the command line statement as mentioned below:
flutter create <YOUR_APP_NAME>To know more about Creating flutter application refer to Creating a Simple Application in Flutter article.
Step 2: Adding Dependencies in the Application
Add jetpack package to your pubspec.yaml file.
jetpack: ^1.0.7 Optional Dependency : Add fluttertoast package to your pubspec.yaml file.
fluttertoast: ^8.2.12Step 3: Working with Main.dart File
Use the below code in the main.dart file for adding functionality to the appliction.
main.dart:
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:jetpack/jetpack.dart';
import 'package:my_app/Models/ViewModel.dart';
// Entry point of the application
void main() {
runApp(const MyApp());
}
// Main application widget
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
// Disable debug banner
debugShowCheckedModeBanner: false,
// Set home widget
home: const JectPackCounter(),
);
}
}
// Event class for counter increment
class CounterIncrementedEvent extends CounterEvent {}
// Widget for JetPack counter
class JectPackCounter extends StatelessWidget {
const JectPackCounter({super.key});
// Function to handle events
Future<void> onEvent(BuildContext context, CounterEvent event) async {
await Fluttertoast.showToast(
msg: "Counter Incremented", // Message to show
toastLength: Toast.LENGTH_SHORT, // Duration of toast
gravity: ToastGravity.BOTTOM, // Position of toast
backgroundColor: Colors.green, // Background color of toast
textColor: Colors.white, // Text color of toast
fontSize: 16.0); // Font size of toast
}
@override
Widget build(BuildContext context) {
// Get ViewModel
final IncrementCounterModel viewModel = context.viewModel();
return Scaffold(
appBar: AppBar(
title: const Text('JetPack Counter'), // App bar title
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center, // Center vertically
crossAxisAlignment: CrossAxisAlignment.center, // Center horizontally
children: [
EventListener(
eventQueue: viewModel.eventQueue, // Event queue from ViewModel
onEvent: onEvent, // Event handler
child: LiveDataBuilder<int>(
liveData: viewModel.counter, // Live data from ViewModel
builder: (BuildContext buildContext, int count) => Text(
'Count: $count', // Display counter value
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green,
),
onPressed: viewModel.increment, // Increment counter on press
child: Text(
"Increment Counter",
style: TextStyle(
color: Colors.white,
),
),
)
],
),
),
);
}
}
// Extension to get ViewModel from BuildContext
extension ViewModelExtension on BuildContext {
IncrementCounterModel viewModel() {
return IncrementCounterModel();
}
}
// Abstract class for counter events
abstract class CounterEvent {}
Refer to Fluttertoast in Flutter to know more about Toast.
Step 4: Creating New File and updating it
Create a new file called ViewModel.dart which is responsible for implementing Business Logic code ,which manages whole flow of the application.
ViewModel.dart:
import 'package:jetpack/jetpack.dart';
import 'package:oyo/main.dart';
// This class represents a ViewModel
// for incrementing a counter
class IncrementCounterModel extends ViewModel
{
// MutableLiveData to hold the counter
// value, initialized to 0
final MutableLiveData<int> _counter = MutableLiveData(0);
// MutableEventQueue to hold events
// related to the counter
final MutableEventQueue<CounterEvent> _eventQueue = MutableEventQueue();
// Getter to expose the counter
// as LiveData
LiveData<int> get counter => _counter;
// Getter to expose the event queue
EventQueue<CounterEvent> get eventQueue => _eventQueue;
// Method to increment the counter and
// push an event to the event queue
void increment() {
_counter.value++;
_eventQueue.push(CounterIncrementedEvent());
}
}
Refer to Getter and Setter Methods in Dart to know more about get.