Skip to content

Commit

Permalink
Support generating android adaptive icons
Browse files Browse the repository at this point in the history
  • Loading branch information
vigorox authored Dec 1, 2023
1 parent 64c3e19 commit 1db434b
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 14 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ flavorizr:
| customConfig | Array | | false | An array which contains a set of custom configs, *overrides defaultConfig* |
| generateDummyAssets | bool | true | false | True if you want to generate dummy assets (icon set, strings, etc) |
| icon | String | | false | The icon path for this android flavor |
| adaptiveIcon | Array | | false | An array which contains foreground and background of adaptive icon |

#### ios (under *flavorname*)

Expand Down Expand Up @@ -354,6 +355,24 @@ apple {
}
```

#### adaptiveIcon (for Android only)

You can define adaptiveIcon for android:
```yml
flavors:
apple:
app:
name: "Apple App"
android:
applicationId: "com.example.apple"
icon: "assets/icon/appleApp/ic_launcher.png"
adaptiveIcon:
foreground: "assets/adaptive_icon/appleApp/ic_launcher_foreground.png"
background: "assets/adaptive_icon/appleApp/ic_launcher_background.png"
```
After removing adaptiveIcon key, the adaptive icons generated before will still exist. Please delete adaptiveIcon manually.


## Usage

Expand Down
4 changes: 2 additions & 2 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: args
sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
async:
dependency: transitive
description:
Expand Down
5 changes: 5 additions & 0 deletions lib/src/parser/models/flavors/android.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/

import 'package:flutter_flavorizr/src/parser/models/flavors/android/adaptive_icon.dart';
import 'package:flutter_flavorizr/src/parser/models/flavors/android/build_config_field.dart';
import 'package:flutter_flavorizr/src/parser/models/flavors/android/res_value.dart';
import 'package:flutter_flavorizr/src/parser/models/flavors/commons/os.dart';
Expand All @@ -49,6 +50,9 @@ class Android extends OS {
@JsonKey(disallowNullValue: true)
final AGConnect? agconnect;

@JsonKey(disallowNullValue: true)
final AdaptiveIcon? adaptiveIcon;

Android({
required this.applicationId,
this.customConfig = const {},
Expand All @@ -58,6 +62,7 @@ class Android extends OS {
bool generateDummyAssets = true,
Firebase? firebase,
String? icon,
this.adaptiveIcon,
}) : super(
generateDummyAssets: generateDummyAssets,
firebase: firebase,
Expand Down
4 changes: 4 additions & 0 deletions lib/src/parser/models/flavors/android.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions lib/src/parser/models/flavors/android/adaptive_icon.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'package:json_annotation/json_annotation.dart';

part 'adaptive_icon.g.dart';

@JsonSerializable(anyMap: true, createToJson: false)
class AdaptiveIcon {
final String foreground;
final String background;

AdaptiveIcon({required this.foreground, required this.background});

factory AdaptiveIcon.fromJson(Map<String, dynamic> json) =>
_$AdaptiveIconFromJson(json);
}
19 changes: 19 additions & 0 deletions lib/src/parser/models/flavors/android/adaptive_icon.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:flutter_flavorizr/src/parser/models/flavorizr.dart';
import 'package:flutter_flavorizr/src/processors/commons/image_resizer_processor.dart';
import 'package:flutter_flavorizr/src/processors/commons/queue_processor.dart';
import 'package:flutter_flavorizr/src/utils/constants.dart';
import 'package:sprintf/sprintf.dart';

class AndroidAdaptiveIconProcessor extends QueueProcessor {
String foregroundSource;
String backgroundSource;
String flavorName;
String folder;
Size size;

AndroidAdaptiveIconProcessor(
this.foregroundSource,
this.backgroundSource,
this.flavorName,
this.folder,
this.size, {
required Flavorizr config,
}) : super([
ImageResizerProcessor(
foregroundSource,
sprintf(K.androidAdaptiveIconForegroundPath, [flavorName, folder]),
size,
config: config,
),
ImageResizerProcessor(
backgroundSource,
sprintf(K.androidAdaptiveIconBackgroundPath, [flavorName, folder]),
size,
config: config,
),
], config: config);

@override
String toString() => 'AndroidAdaptiveIconProcessor';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:flutter_flavorizr/src/parser/models/flavorizr.dart';
import 'package:flutter_flavorizr/src/processors/android/icons/android_generate_iclauncher_xml_processor.dart';
import 'package:flutter_flavorizr/src/processors/commons/new_file_string_processor.dart';
import 'package:flutter_flavorizr/src/processors/commons/queue_processor.dart';
import 'package:flutter_flavorizr/src/utils/constants.dart';
import 'package:sprintf/sprintf.dart';

class AndroidAdaptiveIconXmlProcessor extends QueueProcessor {
AndroidAdaptiveIconXmlProcessor(
String? flavorName, {
required Flavorizr config,
}) : super(
[
NewFileStringProcessor(
sprintf(K.androidAdaptiveIconXmlPath, [flavorName]),
AndroidGenerateIclauncherXmlProcessor(config: config),
config: config,
),
],
config: config,
);

@override
String toString() => 'AndroidAdaptiveIconXmlProcessor';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'package:flutter_flavorizr/src/parser/models/flavorizr.dart';
import 'package:flutter_flavorizr/src/processors/android/icons/android_adaptive_icon_processor.dart';
import 'package:flutter_flavorizr/src/processors/commons/image_resizer_processor.dart';
import 'package:flutter_flavorizr/src/processors/commons/queue_processor.dart';

class AndroidAdaptiveIconsProcessor extends QueueProcessor {
static const _entries = {
'drawable-mdpi': Size(width: 108, height: 108),
'drawable-hdpi': Size(width: 162, height: 162),
'drawable-xhdpi': Size(width: 216, height: 216),
'drawable-xxhdpi': Size(width: 324, height: 324),
'drawable-xxxhdpi': Size(width: 432, height: 432),
};

String foregroundSource;
String backgroundSource;
String flavorName;

AndroidAdaptiveIconsProcessor(
this.foregroundSource,
this.backgroundSource,
this.flavorName, {
required Flavorizr config,
}) : super(
_entries.map(
(folder, size) {
return MapEntry(
folder,
AndroidAdaptiveIconProcessor(
foregroundSource,
backgroundSource,
flavorName,
folder,
size,
config: config,
),
);
},
).values,
config: config,
);

@override
String toString() => 'AndroidAdaptiveIconsProcessor';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import 'package:flutter_flavorizr/src/parser/models/flavorizr.dart';
import 'package:flutter_flavorizr/src/processors/commons/string_processor.dart';

class AndroidGenerateIclauncherXmlProcessor extends StringProcessor {
AndroidGenerateIclauncherXmlProcessor({
required Flavorizr config,
}) : super(
config: config,
);

@override
String execute() {
return '<?xml version="1.0" encoding="utf-8"?>'
'<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">'
'<background android:drawable="@drawable/ic_launcher_background" />'
'<foreground android:drawable="@drawable/ic_launcher_foreground" />'
'</adaptive-icon>';
}

@override
String toString() => 'AndroidGenerateIclauncherXmlProcessor';
}
54 changes: 42 additions & 12 deletions lib/src/processors/android/icons/android_icons_processor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,57 @@

import 'package:flutter_flavorizr/src/extensions/extensions_map.dart';
import 'package:flutter_flavorizr/src/parser/models/flavorizr.dart';
import 'package:flutter_flavorizr/src/processors/android/icons/android_adaptive_icons_processor.dart';
import 'package:flutter_flavorizr/src/processors/android/icons/android_adaptive_icon_xml_processor.dart';
import 'package:flutter_flavorizr/src/processors/android/icons/android_icon_processor.dart';
import 'package:flutter_flavorizr/src/processors/commons/queue_processor.dart';

class AndroidIconsProcessor extends QueueProcessor {
AndroidIconsProcessor({
required Flavorizr config,
}) : super(
config.androidFlavors
.where((_, flavor) =>
flavor.app.icon != null || flavor.android?.icon != null)
.map(
(flavorName, flavor) => MapEntry(
flavorName,
AndroidIconProcessor(
flavor.android!.icon ?? flavor.app.icon ?? '',
[
...config.androidFlavors
.where((_, flavor) =>
flavor.app.icon != null || flavor.android?.icon != null)
.map(
(flavorName, flavor) => MapEntry(
flavorName,
config: config,
AndroidIconProcessor(
flavor.android!.icon ?? flavor.app.icon ?? '',
flavorName,
config: config,
),
),
),
)
.values,
)
.values,
...config.androidFlavors
.where((_, flavor) => flavor.android!.adaptiveIcon != null)
.map(
(flavorName, flavor) => MapEntry(
flavorName,
AndroidAdaptiveIconXmlProcessor(
flavorName,
config: config,
),
),
)
.values,
...config.androidFlavors
.where((_, flavor) => flavor.android!.adaptiveIcon != null)
.map(
(flavorName, flavor) => MapEntry(
flavorName,
AndroidAdaptiveIconsProcessor(
flavor.android!.adaptiveIcon!.foreground,
flavor.android!.adaptiveIcon!.background,
flavorName,
config: config,
),
),
)
.values,
],
config: config,
);

Expand Down
6 changes: 6 additions & 0 deletions lib/src/processors/commons/new_file_string_processor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ class NewFileStringProcessor extends AbstractFileStringProcessor {
processor,
config: config,
);

@override
void execute() {
file.createSync(recursive: true);
super.execute();
}
}
1 change: 1 addition & 0 deletions lib/src/processors/processor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class Processor extends AbstractProcessor<void> {
'android:buildGradle',
'android:dummyAssets',
'android:icons',
'android:adaptiveIcons',

// Flutter
'flutter:flavors',
Expand Down
9 changes: 9 additions & 0 deletions lib/src/utils/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ class K {
static String androidIconPath =
'$androidAppPath/src/%s/res/%s/ic_launcher.png';

static String androidAdaptiveIconBackgroundPath =
'$androidAppPath/src/%s/res/%s/ic_launcher_background.png';

static String androidAdaptiveIconForegroundPath =
'$androidAppPath/src/%s/res/%s/ic_launcher_foreground.png';

static String androidAdaptiveIconXmlPath =
'$androidAppPath/src/%s/res/mipmap-anydpi-v26/ic_launcher.xml';

static String androidManifestPath =
'$androidSrcPath/main/AndroidManifest.xml';

Expand Down

0 comments on commit 1db434b

Please sign in to comment.