Skip to content

Commit

Permalink
Release 4.0.0
Browse files Browse the repository at this point in the history
- Added support for using the loader in `StatelessWidget` too
- Using [`stream_mixin`](https://pub.dev/packages/stream_mixin/) instead of state to show/hide loader
- **BREAKING CHANGE**: Use `build` instead of `screen` function
- **BREAKING CHANGE**: `ScreenLoaderApp` widget is removed, use `configScreenLoader` function instead
  • Loading branch information
arnold-parge committed Dec 12, 2021
1 parent 5d4bff5 commit 1dc5de9
Show file tree
Hide file tree
Showing 6 changed files with 249 additions and 167 deletions.
48 changes: 25 additions & 23 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,57 @@
## [3.0.2]
## 4.0.0

* Added support for using the loader in `StatelessWidget` too
* Using [`stream_mixin`](https://pub.dev/packages/stream_mixin/) instead of state to show/hide loader
* **BREAKING CHANGE**: Use `build` instead of `screen` function
* **BREAKING CHANGE**: `ScreenLoaderApp` widget is removed, use `configScreenLoader` function instead

## 3.0.2

* Fixed: [Issue #6](https://github.com/arnold-parge/screen_loader/issues/6): Screen is always blurry

## [3.0.1]
## 3.0.1

* Updated README

## [3.0.0]
## 3.0.0

* Migrating to null safety

## [2.0.1]
* Updated readme as per the previous version's breaking changes
## 2.0.1

## [2.0.0]
* Updated readme as per the previous version's breaking changes

### BREAKING CHANGE
* `screenWrapper` function removed
## 2.0.0
* **BREAKING CHANGE**: `screenWrapper` function removed
* Now just override `screen` function instead of `build` function in your `StatefulWidget`s

## [1.1.1]
## 1.1.1

* Updated readme

## 1.1.0

## [1.1.0]

### Breaking changes
* Removed state parameter from `screenWrapper` function
* **BREAKING CHANGE**: Removed state parameter from `screenWrapper` function
* Added performFuture
* Added BasicScreen in example
* Added loadingBgBlur in ScreenLoader


## [1.0.4]
## 1.0.4

* Updated description


## [1.0.3]
## 1.0.3

* Added example


## [1.0.2]
## 1.0.2

* Updated description in pubspec.yaml


## [1.0.1]
## 1.0.1

* Updated description in pubspec.yaml


## [1.0.0]
## 1.0.0

* Initial release
157 changes: 113 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,25 @@
# screen_loader

Using `showDialog` for showing loader is a **BAD IDEA**. You may end up messing the navigation stack and `context` due to pushing and popping the loader(dialog). Hence, I have come up with an easy to use mixin `ScreenLoader`, which will handle the loading on the screen. You can customise the loading as well, check below how it is done.

## Important
Replace your `build(BuildContext context)` function with `screen(BuildContext context)`

```dart
@override
Widget screen(BuildContext context) {
return Scaffold(
appBar: _buildAppBar(),
body: _buildBody(),
);
}
```

## Basic Usage

Extend your screen(`StatefulWidget`) with `ScreenLoader`. Use `performFuture` to show loader while your future us being performed. That's it!
## Why ScreenLoader?
1. With the help of [`stream_mixin`](https://pub.dev/packages/stream_mixin/), it shows and hides the loader without updating the state of the widget which increases the performance
1. It does not push any sort of widget to navigation stack, this helps in not messing up the navigation stack and context
1. Easy to use, just use your screen with `ScreenLoader` mixin and wrap the widget with `loadableWidget`
1. The loader is customizable. You can use any widget as a loader
1. You can configure same loader for all the screens at once
1. You can also configure different loader for different screens

---
## Basic usage
1. Use your screen with the `ScreenLoader` mixin
1. Wrap the widget with `loadableWidget`
1. Use `performFuture` function to show loader while your future is being performed

<img src="https://raw.githubusercontent.com/arnold-parge/screen_loader/master/example/basic.gif" width="250" />

## Override Loader

Simply overide `loader()` method in your `_ScreenState` class
---
## Configure different loader for individual screen

Simply overide `loader()` method
```
loader() {
// here any widget would do
Expand All @@ -36,39 +31,113 @@ loader() {

<img src="https://raw.githubusercontent.com/arnold-parge/screen_loader/master/example/local.gif" width="250" />

## Override Loader Gobally
---
## Configure the loader for all screens at once

```dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScreenLoaderApp(
app: MaterialApp(
title: AppStrings.yapChat,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Screen(),
),
globalLoader: AlertDialog(
title: Text('Gobal Loader..'),
),
);
}
void main() {
configScreenLoader(
loader: AlertDialog(
title: Text('Gobal Loader..'),
),
bgBlur: 20.0,
);
runApp(MyApp());
}
```

<img src="https://raw.githubusercontent.com/arnold-parge/screen_loader/master/example/global.gif" width="250" />

## Priority of loaders
---
## Priority of loaders (_highest first_)

- **Local loader**: the one you override in the `_ScreenState` class
- **Global loader**: the one you specify in `ScreenLoaderApp`. Note: if you don't override `local()`, this loader will be used.
- **Local loader**: the one you override in your widget
- **Global loader**: the one you specify in `configScreenLoader`. Note: if you don't override `local()`, this loader will be used
- **Default loader**: if you don't specify global loader or override local loader, this loader will be used

---
# Migration guide to 4.0.0
1. `ScreenLoaderApp` widget is removed. Now no need to wrap your App around any widget just to set the global configurations. Instead call `configScreenLoader()` before `runApp()`
```diff
-void main() => runApp(MyApp());
+void main() {
+ configScreenLoader(
+ loader: AlertDialog(
+ title: Text('Gobal Loader..'),
+ ),
+ bgBlur: 20.0,
+ );
+ runApp(MyApp());
+}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return ScreenLoaderApp(
- app: MaterialApp(
- debugShowCheckedModeBanner: false,
- title: 'Screen Loader',
- theme: ThemeData(
- primarySwatch: Colors.blue,
- ),
- home: Screen(),
- ),
- globalLoader: AlertDialog(
- title: Text('Gobal Loader..'),
+ return MaterialApp(
+ debugShowCheckedModeBanner: false,
+ title: 'Screen Loader',
+ theme: ThemeData(
+ primarySwatch: Colors.blue,
),
- globalLoadingBgBlur: 20.0,
+ home: Screen(),
);
}
}
```
2. Instead of replacing the `build` function with `screen` use the `build` function itself and wrap the widget you want to show loader on with the `loadableWidget`.
```diff

-class _ScreenState extends State<Screen> with ScreenLoader<Screen> {
+class _ScreenState extends State<Screen> with ScreenLoader {
@override
loader() {
return AlertDialog(
@@ -49,17 +51,19 @@ class _ScreenState extends State<Screen> with ScreenLoader<Screen> {
}

@override
- Widget screen(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('ScreenLoader Example'),
- ),
- body: _buildBody(),
- floatingActionButton: FloatingActionButton(
- onPressed: () async {
- await this.performFuture(NetworkService.getData);
- },
- child: Icon(Icons.refresh),
+ Widget build(BuildContext context) {
+ return loadableWidget(
+ child: Scaffold(
+ appBar: AppBar(
+ title: Text('ScreenLoader Example'),
+ ),
+ body: _buildBody(),
+ floatingActionButton: FloatingActionButton(
+ onPressed: () async {
+ await this.performFuture(NetworkService.getData);
+ },
+ child: Icon(Icons.refresh),
+ ),
),
);
}
```

---
### PS
- PRs are welcome
- Please raise issues on https://github.com/arnold-parge/screen_loader.
Expand Down
96 changes: 50 additions & 46 deletions example/main.dart
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import 'package:flutter/material.dart';
import 'package:screen_loader/screen_loader.dart';

void main() => runApp(MyApp());
void main() {
configScreenLoader(
loader: AlertDialog(
title: Text('Gobal Loader..'),
),
bgBlur: 20.0,
);
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScreenLoaderApp(
app: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Screen Loader',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Screen(),
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Screen Loader',
theme: ThemeData(
primarySwatch: Colors.blue,
),
globalLoader: AlertDialog(
title: Text('Gobal Loader..'),
),
globalLoadingBgBlur: 20.0,
home: Screen(),
);
}
}
Expand All @@ -28,7 +30,8 @@ class Screen extends StatefulWidget {
_ScreenState createState() => _ScreenState();
}

class _ScreenState extends State<Screen> with ScreenLoader<Screen> {
/// A Stateful screen
class _ScreenState extends State<Screen> with ScreenLoader {
@override
loader() {
return AlertDialog(
Expand All @@ -49,46 +52,47 @@ class _ScreenState extends State<Screen> with ScreenLoader<Screen> {
}

@override
Widget screen(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('ScreenLoader Example'),
),
body: _buildBody(),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await this.performFuture(NetworkService.getData);
},
child: Icon(Icons.refresh),
Widget build(BuildContext context) {
return loadableWidget(
child: Scaffold(
appBar: AppBar(
title: Text('ScreenLoader Example'),
),
body: _buildBody(),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await this.performFuture(NetworkService.getData);
},
child: Icon(Icons.refresh),
),
),
);
}
}

class BasicScreen extends StatefulWidget {
@override
_BasicScreenState createState() => _BasicScreenState();
}
/// A Stateless screen
class BasicScreen extends StatelessWidget with ScreenLoader {
BasicScreen({ Key? key }) : super(key: key);

class _BasicScreenState extends State<BasicScreen>
with ScreenLoader<BasicScreen> {
@override
Widget screen(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Basic ScreenLoader Example'),
),
body: Center(
child: Icon(
Icons.home,
size: MediaQuery.of(context).size.width,
Widget build(BuildContext context) {
return loadableWidget(
child: Scaffold(
appBar: AppBar(
title: Text('Basic ScreenLoader Example'),
),
body: Center(
child: Icon(
Icons.home,
size: MediaQuery.of(context).size.width,
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await this.performFuture(NetworkService.getData);
},
child: Icon(Icons.refresh),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await this.performFuture(NetworkService.getData);
},
child: Icon(Icons.refresh),
),
);
}
Expand Down
Loading

0 comments on commit 1dc5de9

Please sign in to comment.