clean_init
A Flutter package that provides a simple and flexible initialization framework for your applications.
Features
- Bootstrap initialization with state management
- Built-in provider - no need to add it to your provider list
- Customizable initialization states (loading, error, initialized)
- Loading progress tracking with optional progress and stage data
- Flexible UI customization with both widget and builder options
- Clean separation of concerns
Usage
Basic Example
import 'package:clean_init/clean_init.dart';
CleanInitContainer(
init: (setInitState) async {
try {
// Your initialization logic
await loadConfig();
await initializeServices();
setInitState(CleanInitState.initialized);
} catch (e) {
setInitState(CleanInitState.error(ErrorData(message: e.toString())));
}
},
initializedWidget: YourMainApp(),
)
With Custom Loading and Error UI
CleanInitContainer(
init: (setInitState) async {
try {
setInitState(CleanInitState.loading);
// Track progress
setInitState(CleanInitState.loadingWithData(
LoadingData(progress: 0.5, stage: 1),
));
await Future.delayed(Duration(seconds: 2));
setInitState(CleanInitState.initialized);
} catch (e) {
setInitState(CleanInitState.error(ErrorData(message: e.toString())));
}
},
loadingWidget: Center(child: CircularProgressIndicator()),
errorWidget: Center(child: Text('Something went wrong!')),
initializedWidget: YourMainApp(),
)
Using Builders for Advanced Customization
CleanInitContainer(
init: (setInitState) async {
// Your init logic
},
loadingBuilder: (state) {
final loadingData = state.loadingData;
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(
value: loadingData?.progress,
),
if (loadingData?.stage != null)
Text('Stage: ${loadingData!.stage}'),
],
),
);
},
errorBuilder: (state) {
return Center(
child: Text('Error: ${state.errorData?.message ?? "Unknown"}'),
);
},
initializedBuilder: (state) => YourMainApp(),
)
API Reference
CleanInitContainer
| Parameter | Type | Required | Description |
|---|---|---|---|
init |
InitFunction |
Yes | Async function that handles initialization |
loadingWidget |
Widget? |
No | Static widget shown during loading |
loadingBuilder |
Widget Function(CleanInitState)? |
No | Builder for loading state with access to state |
errorWidget |
Widget? |
No | Static widget shown on error |
errorBuilder |
Widget Function(CleanInitState)? |
No | Builder for error state with access to state |
initializedWidget |
Widget? |
No* | Static widget shown when initialized |
initializedBuilder |
Widget Function(CleanInitState)? |
No* | Builder for initialized state with access to state |
Note: You must provide either initializedWidget OR initializedBuilder (but not both). For loading and error states, both widget and builder are optional, but you cannot provide both for the same state.
CleanInitState
States:
CleanInitState.loading- Initial loading stateCleanInitState.loadingWithData(LoadingData)- Loading with progress trackingCleanInitState.initialized- Successfully initializedCleanInitState.error(ErrorData)- Error state
LoadingData
LoadingData({
double? progress, // 0.0 to 1.0
int? stage, // Current stage number
})
ErrorData
ErrorData supports different error types with specialized handling:
// General error
ErrorData({
required String message,
ErrorType type = ErrorType.general, // optional
})
// Or use convenience constructor
ErrorData.general('Error message')
// Version deprecated error (with additional version info)
ErrorData.versionDeprecated({
required String currentVersion,
required String minVersion,
required String downloadUrl,
})
Error Types:
ErrorType.general- Standard initialization errorErrorType.versionDeprecated- App version is outdated (includesVersionErrorData)ErrorType.maintenance- App is under maintenance (includesMaintenanceData)
VersionErrorData (available when type == ErrorType.versionDeprecated):
class VersionErrorData {
final String currentVersion;
final String minVersion;
final String downloadUrl;
}
MaintenanceData (available when type == ErrorType.maintenance):
class MaintenanceData {
final DateTime? dueDate; // Expected maintenance completion time
}
Example - Handling Different Error Types:
errorBuilder: (state) {
final errorData = state.errorData;
if (errorData?.type == ErrorType.versionDeprecated) {
// Show custom update UI with download button
return UpdateRequiredScreen(
versionData: errorData!.versionData!,
);
}
if (errorData?.type == ErrorType.maintenance) {
// Show maintenance screen with optional due date
return MaintenanceScreen(
maintenanceData: errorData!.maintenanceData!,
message: errorData.message,
);
}
// Default error handling
return ErrorScreen(message: errorData?.message ?? 'Unknown error');
},
Example - Setting Maintenance State:
// In your initialization logic
if (configProvider.isUnderMaintenance) {
setInitState(CleanInitState.error(
ErrorData.maintenance(
message: 'We are currently performing scheduled maintenance',
dueDate: DateTime(2025, 10, 20, 14, 0), // Optional
),
));
return;
}
License
MIT