updateStylesXml function
Updates values/styles.xml for pre-Android 12 splash style references.
If android_12_and_above is present, this recreates
values-v31/styles.xml using only values from that block.
If hasDarkDrawable is false, this also ensures any existing night
styles don't reference the dark drawable
Implementation
Future<void> updateStylesXml({
YamlMap? android12AndAbove,
bool hasDarkDrawable = false,
}) async {
const androidValuesFolder = CmdStrings.androidValuesDirectory;
// Only use values explicitly set under android_12_and_above.
// Top-level color and image are not inherited by Android 12+.
if (android12AndAbove != null) {
const v31 = CmdStrings.androidValuesV31Directory;
await _ensureDirectoryExists(v31);
const style = '$v31/${AndroidStrings.stylesXml}';
if (await File(style).exists()) {
await File(style).delete();
}
final styleFile = File(style);
await createAndroid12Styles(
styleFile: styleFile,
color: android12AndAbove[YamlKeys.colorKey] as String?,
imageSource: android12AndAbove[YamlKeys.imageKey] as String?,
brandingImageSource: android12AndAbove[YamlKeys.brandingImageKey],
);
}
final xml = File('$androidValuesFolder/${AndroidStrings.stylesXml}');
final xmlExists = await xml.exists();
if (!xmlExists) {
log("styles.xml doesn't exists");
return;
}
final xmlDoc = XmlDocument.parse(xml.readAsStringSync());
xmlDoc.findAllElements(AndroidStrings.itemElement).where((itemElement) {
return itemElement.getAttribute(AndroidStrings.nameAttr) ==
AndroidStrings.itemNameAttrValue;
}).forEach((itemElement) {
itemElement.setAttribute(
AndroidStrings.nameAttr,
AndroidStrings.itemNameAttrValue,
);
itemElement.innerText = AndroidStrings.drawableSplashScreen;
});
await xml.writeAsString(xmlDoc.toXmlString(pretty: true));
log('styles.xml updated.');
// Ensure any existing pre-Android 12 night styles don't reference the
// dark drawable when the user hasn't provided dark-mode pre-Android 12
// assets in pubspec. This prevents references to missing
// `@drawable/splash_screen_dark` and points night styles to the light
// drawable instead so resource linking succeeds.
if (!hasDarkDrawable) {
try {
const nightValuesPath =
'${CmdStrings.androidDarkValuesDirectory}/${AndroidStrings.stylesXml}';
final nightFile = File(nightValuesPath);
if (await nightFile.exists()) {
final nightDoc = XmlDocument.parse(nightFile.readAsStringSync());
var changed = false;
for (final itemElement
in nightDoc.findAllElements(AndroidStrings.itemElement)) {
if (itemElement.getAttribute(AndroidStrings.nameAttr) ==
AndroidStrings.itemNameAttrValue) {
if (itemElement.innerText.trim() ==
AndroidStrings.androidDarkDrawable) {
itemElement.innerText = AndroidStrings.drawableSplashScreen;
changed = true;
}
}
}
if (changed) {
await nightFile.writeAsString(nightDoc.toXmlString(pretty: true));
log('values-night/styles.xml updated to reference light drawable.');
}
}
} catch (e) {
log('Error updating values-night/styles.xml: $e');
}
}
}