Skip to content

Commit

Permalink
Adds null safety. Closes #127.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Hanson committed Feb 19, 2021
1 parent 30a7356 commit 477005d
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 139 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,7 @@
## [1.0.0] - (2021-Feb-19)

* Adds null safety. Closes [#127](https://github.com/jonbhanson/flutter_native_splash/issues/127).

## [0.3.0] - (2021-Feb-10)

* Added support for web. Closes [#30](https://github.com/jonbhanson/flutter_native_splash/issues/30).
Expand Down
5 changes: 3 additions & 2 deletions README.md
Expand Up @@ -13,7 +13,7 @@ First, add `flutter_native_splash` as a dev dependency in your pubspec.yaml file

```yaml
dev_dependencies:
flutter_native_splash: ^0.3.0
flutter_native_splash: ^1.0.0
```

Don't forget to `flutter pub get`.
Expand Down Expand Up @@ -105,6 +105,7 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder(
// Replace the 3 second delay with your initialization code:
future: Future.delayed(Duration(seconds: 3)),
builder: (context, AsyncSnapshot snapshot) {
// Show splash screen while waiting for app resources to load:
Expand Down Expand Up @@ -153,7 +154,7 @@ Not at this time. However, you may want to consider a secondary splash screen t
# Notes
* If splash screen was not updated properly on iOS or if you experience a white screen before splash screen, run `flutter clean` and recompile your app. If that does not solve the problem, delete your app from the device, power down the device, power up device, install and launch app as per [this stackoverflow thread](https://stackoverflow.com/questions/33002829/ios-keeping-old-launch-screen-and-app-icon-after-update).

* This package modifies `launch_background.xml`, and `styles.xml` files on Android and `LaunchScreen.storyboard`, and `Info.plist` on iOS. If you modified this files manually this plugin may not work properly, please [open an issue](https://github.com//jonbhanson/flutter_native_splash/issues/new?template=bug_report.md) if you find any bugs.
* This package modifies `launch_background.xml` and `styles.xml` files on Android, `LaunchScreen.storyboard` and `Info.plist` on iOS, and `index.html` on Web. If you have modified these files manually, this plugin may not work properly. Please [open an issue](https://github.com//jonbhanson/flutter_native_splash/issues/new?template=bug_report.md) if you find any bugs.

# How it works
## Android
Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Expand Up @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1

environment:
sdk: ">=2.7.0 <3.0.0"
sdk: '>=2.12.0-0 <3.0.0'

dependencies:
flutter:
Expand Down
79 changes: 48 additions & 31 deletions lib/android.dart
Expand Up @@ -4,7 +4,8 @@ part of flutter_native_splash_supported_platform;
class _AndroidDrawableTemplate {
final String directoryName;
final double divider;
_AndroidDrawableTemplate({this.directoryName, this.divider});
_AndroidDrawableTemplate(
{required this.directoryName, required this.divider});
}

final List<_AndroidDrawableTemplate> _splashImages = <_AndroidDrawableTemplate>[
Expand All @@ -27,13 +28,13 @@ final List<_AndroidDrawableTemplate> _splashImagesDark =
];

/// Create Android splash screen
void _createAndroidSplash(
{String imagePath,
String darkImagePath,
String color,
String darkColor,
String gravity,
bool fullscreen}) async {
Future<void> _createAndroidSplash(
{required String imagePath,
required String darkImagePath,
required String color,
required String darkColor,
required String gravity,
required bool fullscreen}) async {
if (imagePath.isNotEmpty) {
await _applyImageAndroid(imagePath: imagePath);
}
Expand Down Expand Up @@ -87,7 +88,8 @@ void _createAndroidSplash(
}

/// Create splash screen as drawables for multiple screens (dpi)
void _applyImageAndroid({String imagePath, bool dark = false}) {
Future<void> _applyImageAndroid(
{required String imagePath, bool dark = false}) async {
print('[Android] Creating ' + (dark ? 'dark mode ' : '') + 'splash images');

final file = File(imagePath);
Expand All @@ -97,6 +99,9 @@ void _applyImageAndroid({String imagePath, bool dark = false}) {
}

final image = decodeImage(File(imagePath).readAsBytesSync());
if (image == null) {
throw _NoImageFileFoundException('The file $imagePath could not be read.');
}

for (var template in dark ? _splashImagesDark : _splashImages) {
_saveImageAndroid(template: template, image: image);
Expand All @@ -106,7 +111,8 @@ void _applyImageAndroid({String imagePath, bool dark = false}) {
/// Saves splash screen image to the project
/// Note: Do not change interpolation unless you end up with better results
/// https://github.com/fluttercommunity/flutter_launcher_icons/issues/101#issuecomment-495528733
void _saveImageAndroid({_AndroidDrawableTemplate template, Image image}) {
void _saveImageAndroid(
{required _AndroidDrawableTemplate template, required Image image}) {
var newFile = copyResize(
image,
width: image.width ~/ template.divider,
Expand All @@ -123,9 +129,9 @@ void _saveImageAndroid({_AndroidDrawableTemplate template, Image image}) {

/// Create or update launch_background.xml adding splash image path
Future _applyLaunchBackgroundXml({
String gravity,
String launchBackgroundFilePath,
bool showImage,
required String gravity,
required String launchBackgroundFilePath,
required bool showImage,
}) {
final launchBackgroundFile = File(launchBackgroundFilePath);

Expand Down Expand Up @@ -157,7 +163,9 @@ Future _applyLaunchBackgroundXml({

/// Updates launch_background.xml adding splash image path
Future _updateLaunchBackgroundFileWithImagePath(
{String launchBackgroundFilePath, String gravity, bool showImage}) async {
{required String launchBackgroundFilePath,
required String gravity,
required bool showImage}) async {
final launchBackgroundFile = File(launchBackgroundFilePath);
var launchBackgroundDocument;
if (launchBackgroundFile.existsSync()) {
Expand Down Expand Up @@ -190,7 +198,7 @@ Future _updateLaunchBackgroundFileWithImagePath(
if (showImage) {
var splashItem =
XmlDocument.parse(_androidLaunchBackgroundItemXml).rootElement.copy();
splashItem.getElement('bitmap').setAttribute('android:gravity', gravity);
splashItem.getElement('bitmap')?.setAttribute('android:gravity', gravity);
items.add(splashItem);
}
launchBackgroundFile.writeAsStringSync(
Expand All @@ -199,22 +207,24 @@ Future _updateLaunchBackgroundFileWithImagePath(

/// Creates launch_background.xml with splash image path
Future _createLaunchBackgroundFileWithImagePath(
{String gravity, String launchBackgroundFilePath, bool showImage}) async {
{required String gravity,
required String launchBackgroundFilePath,
required bool showImage}) async {
var file = await File(launchBackgroundFilePath).create(recursive: true);
var fileContent = XmlDocument.parse(_androidLaunchBackgroundXml);

if (showImage) {
var splashItem =
XmlDocument.parse(_androidLaunchBackgroundItemXml).rootElement.copy();
splashItem.getElement('bitmap').setAttribute('android:gravity', gravity);
fileContent.getElement('layer-list').children.add(splashItem);
splashItem.getElement('bitmap')?.setAttribute('android:gravity', gravity);
fileContent.getElement('layer-list')?.children.add(splashItem);
}
return await file
.writeAsString(fileContent.toXmlString(pretty: true, indent: ' '));
}

/// Create or update colors.xml adding splash screen background color
Future<void> _applyColor({color, String colorFile}) async {
Future<void> _applyColor({color, required String colorFile}) async {
var colorsXml = File(colorFile);

color = '#' + color;
Expand All @@ -233,7 +243,8 @@ Future<void> _applyColor({color, String colorFile}) async {
}

/// Updates the colors.xml with the splash screen background color
void _updateColorsFileWithColor({File colorsFile, String color}) {
void _updateColorsFileWithColor(
{required File colorsFile, required String color}) {
final lines = colorsFile.readAsLinesSync();
var foundExisting = false;

Expand Down Expand Up @@ -264,7 +275,7 @@ void _updateColorsFileWithColor({File colorsFile, String color}) {
}

/// Creates a colors.xml file if it was missing from android/app/src/main/res/values/colors.xml
void _createColorsFile({String color, File colorsXml}) {
void _createColorsFile({required String color, required File colorsXml}) {
colorsXml.create(recursive: true).then((File colorsFile) {
colorsFile.writeAsString(_androidColorsXml).then((File file) {
_updateColorsFileWithColor(colorsFile: colorsFile, color: color);
Expand All @@ -277,7 +288,7 @@ void _createColorsFile({String color, File colorsXml}) {
///
/// Note: default color = "splash_color"
Future _overwriteLaunchBackgroundWithNewSplashColor(
{String color, String launchBackgroundFilePath}) async {
{required String color, required String launchBackgroundFilePath}) async {
final launchBackgroundFile = File(launchBackgroundFilePath);
final lines = await launchBackgroundFile.readAsLines();

Expand All @@ -302,7 +313,7 @@ Future _overwriteLaunchBackgroundWithNewSplashColor(
}

/// Create or update styles.xml full screen mode setting
Future<void> _applyStylesXml({bool fullScreen}) async {
Future<void> _applyStylesXml({required bool fullScreen}) async {
final stylesFile = File(_androidStylesFile);

if (!stylesFile.existsSync()) {
Expand All @@ -316,7 +327,8 @@ Future<void> _applyStylesXml({bool fullScreen}) async {
}

/// Updates styles.xml adding full screen property
Future<void> _updateStylesFile({bool fullScreen, File stylesFile}) async {
Future<void> _updateStylesFile(
{required bool fullScreen, required File stylesFile}) async {
final stylesDocument = XmlDocument.parse(await stylesFile.readAsString());
final styles = stylesDocument.findAllElements('style');
if (styles.length == 1) {
Expand All @@ -325,19 +337,24 @@ Future<void> _updateStylesFile({bool fullScreen, File stylesFile}) async {
'embedding. Skipping update of styles.xml with fullscreen mode');
return;
}
var found = true;
final launchTheme = styles.firstWhere(
(element) => (element.attributes.any((attribute) =>
attribute.name.toString() == 'name' &&
attribute.value == 'LaunchTheme')),
orElse: () => null);
if (launchTheme != null) {
attribute.value == 'LaunchTheme')), orElse: () {
found = false;
return XmlElement(XmlName('dummy'));
});
if (found) {
final fullScreenElement = launchTheme.children.firstWhere(
(element) => (element.attributes.any((attribute) {
return attribute.name.toString() == 'name' &&
attribute.value == 'android:windowFullscreen';
})),
orElse: () => null);
if (fullScreenElement == null) {
})), orElse: () {
found = false;
return XmlElement(XmlName('dummy'));
});
if (found) {
launchTheme.children.add(XmlElement(
XmlName('item'),
[XmlAttribute(XmlName('name'), 'android:windowFullscreen')],
Expand All @@ -354,7 +371,7 @@ Future<void> _updateStylesFile({bool fullScreen, File stylesFile}) async {
}

/// Creates styles.xml with full screen property
void _createStylesFileWithImagePath({File stylesFile}) {
void _createStylesFileWithImagePath({required File stylesFile}) {
stylesFile.createSync(recursive: true);
stylesFile.writeAsStringSync(_androidStylesXml);
}
12 changes: 6 additions & 6 deletions lib/exceptions.dart
@@ -1,7 +1,7 @@
part of flutter_native_splash_supported_platform;

class _NoConfigFoundException implements Exception {
const _NoConfigFoundException([this.message]);
const _NoConfigFoundException(this.message);
final String message;

@override
Expand All @@ -13,7 +13,7 @@ class _NoConfigFoundException implements Exception {
}

class _InvalidConfigException implements Exception {
const _InvalidConfigException([this.message]);
const _InvalidConfigException(this.message);
final String message;

@override
Expand All @@ -25,7 +25,7 @@ class _InvalidConfigException implements Exception {
}

class _NoImageFileFoundException implements Exception {
const _NoImageFileFoundException([this.message]);
const _NoImageFileFoundException(this.message);
final String message;

@override
Expand All @@ -37,7 +37,7 @@ class _NoImageFileFoundException implements Exception {
}

class _InvalidNativeFile implements Exception {
const _InvalidNativeFile([this.message]);
const _InvalidNativeFile(this.message);
final String message;

@override
Expand All @@ -49,7 +49,7 @@ class _InvalidNativeFile implements Exception {
}

class _LaunchScreenStoryboardModified implements Exception {
const _LaunchScreenStoryboardModified([this.message]);
const _LaunchScreenStoryboardModified(this.message);
final String message;

@override
Expand All @@ -61,7 +61,7 @@ class _LaunchScreenStoryboardModified implements Exception {
}

class _CantFindInfoPlistFile implements Exception {
const _CantFindInfoPlistFile([this.message]);
const _CantFindInfoPlistFile(this.message);
final String message;

@override
Expand Down

0 comments on commit 477005d

Please sign in to comment.