page_state_builder 0.0.1
page_state_builder: ^0.0.1 copied to clipboard
A Flutter package that helps manage loading, success, and error states in your UI with customizable builders.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:example/responsive_page_wrapper.dart';
import 'package:get/get.dart';
import 'package:page_state_builder/page_state_builder.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'PageStateBuilder Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.light,
),
useMaterial3: true,
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.dark,
),
useMaterial3: true,
),
themeMode: ThemeMode.system,
home: DemoPage(),
);
}
}
/// Controller that handles the business logic of the demo page.
/// It uses GetX for reactive state management.
class DemoController extends GetxController {
/// Observable state that determines the UI to show.
var state = PageState.loading.obs;
/// Observable error message used when the state is in [PageState.error].
var errorMessage = ''.obs;
/// Simulates data loading. Randomly succeeds or fails after a delay.
void loadData() async {
state.value = PageState.loading;
// Simulate loading delay
await Future.delayed(Duration(seconds: 2));
// Randomly set state to success or error
if (DateTime.now().second % 2 == 0) {
state.value = PageState.success;
} else {
state.value = PageState.error;
errorMessage.value = "Failed to load data";
}
}
}
/// A simple demo page that demonstrates how to use [PageStateBuilder]
/// with GetX reactive state management.
///
/// [PageStateBuilder] is a widget that conditionally builds UI based on a state.
/// - When `state` is [PageState.loading], it shows a loading widget.
/// - When `state` is [PageState.error], it shows an error widget (with retry).
/// - When `state` is [PageState.success], it shows the content provided by `successBuilder`.
///
/// The loading and error widgets are customizable by passing custom builders
/// like `loadingBuilder` and `errorBuilder`.
class DemoPage extends StatelessWidget {
/// Register the controller using Get.put to enable dependency injection.
final controller = Get.put(DemoController());
DemoPage({super.key});
@override
Widget build(BuildContext context) {
/// The responsive page wrapper is optional, to view the widgets in adaptative screen sizes
return ResponsivePageWrapper(
child: Scaffold(
appBar: AppBar(title: Text('Simple GetX Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Reactive observer that rebuilds when state or errorMessage changes
Obx(
() => PageStateBuilder(
state: controller.state.value,
errorMessage: controller.errorMessage.value,
onRetry: controller.loadData,
successBuilder: (_) => Text(
'Success!',
style: TextStyle(fontSize: 24),
),
// You can also optionally provide:
// loadingBuilder: (_) => CustomLoadingWidget(),
// errorBuilder: (msg, onRetry) => CustomErrorWidget(msg: msg, onRetry: onRetry),
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: controller.loadData,
child: Text('Reload'),
),
],
),
),
),
);
}
}