Sort Drawables Build Script
In many projects I got drawable files in the format ic_sun@1x.png
, ic_sun@2x.png
and ic_sun@3x.png
. I created a script that automatically sorts the files into the drawables folders.
Usage
Copy the script below into your buildSrc/java
folder and add the following line to your app/build.gradle
file:
apply plugin: SortDrawablesPlugin
Then put the files you got from you designer in the main res folder and run the script:
gradlew.bat app:sortDrawables
Files that have the string @1x
or _1x
in their name will be stripped of this string and placed in th drawable-mdpi
folder. Files with @2x
will be placed in xhdpi, @3x
goes to xxhdpi and so on.
The script will not override already existing files. To replace exiting files call gradlew.bat app:sortDrawablesOverride
Example
Files before running the script:
project\app\src\main\res\drawable-mdpi\ic_moon.png
project\app\src\main\res\drawable-xhdpi\ic_moon.png
project\app\src\main\res\drawable-xxhdpi\ic_moon.png
project\app\src\main\res\ic_sun@1.png
project\app\src\main\res\ic_sun@2.png
project\app\src\main\res\ic_sun@3.png
The script runs:
> gradle app:sortDrawables
:app:sortDrawables
Looking for images in project\app\src\main\res
Sort ic_sun@1x.png to: project\app\src\main\res\drawable-mdpi\ic_sun.png
Sort ic_sun@2x.png to: project\app\src\main\res\drawable-xhdpi\ic_sun.png
Sort ic_sun@3x.png to: project\app\src\main\res\drawable-xxhdpi\ic_sun.png
Files after running the script:
project\app\src\main\res\drawable-mdpi\ic_moon.png
project\app\src\main\res\drawable-mdpi\ic_sun.png
project\app\src\main\res\drawable-xhdpi\ic_moon.png
project\app\src\main\res\drawable-xhdpi\ic_sun.png
project\app\src\main\res\drawable-xxhdpi\ic_moon.png
project\app\src\main\res\drawable-xxhdpi\ic_sun.png
The Script
/*
* Copyright 2016 Max Nagl
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.gradle.api.Plugin
import org.gradle.api.Project
class SortDrawablesPlugin implements Plugin<Project> {
def resolutions = ['0.75': 'mdpi', '1': 'mdpi', '1.5': 'hdpi', '2': 'xhdpi', '3': 'xxhdpi', '4': 'xxxhdpi'];
def tags = ['@#x', '_#x'];
void apply(Project project) {
project.task('sortDrawables') << { sortDrawables(project, false); }
project.task('sortDrawablesOverride') << { sortDrawables(project, true); }
}
public void sortDrawables(Project project, boolean override) {
File resDir = new File(project.projectDir, "src/main/res");
def tagsToFolders = [:];
resolutions.each { resoltion, folder ->
tags.each { tag ->
tagsToFolders.put(tag.replace('#', resoltion), new File(resDir, 'drawable-' + folder));
};
};
println "Looking for images in " + resDir.absolutePath;
for (File file : resDir.listFiles()) {
if (file.isDirectory()) continue;
String name = file.getName().toLowerCase();
if (file.getName().endsWith(".png") || file.getName().endsWith(".jpg") || file.getName().endsWith(".gif")) {
File sortTo = null;
tagsToFolders.each { tag, folder ->
if (name.contains((String) tag)) {
sortTo = new File((File) folder, name.replace((String) tag, ''));
return false;
}
};
if (!sortTo.parentFile.exists()) {
println "Create folder " + sortTo.parentFile;
sortTo.parentFile.mkdirs();
}
if (sortTo != null) {
println "Sort " + file.name + " to: " + sortTo;
if (sortTo.exists()) {
if (override) {
println "Overriding file: " + sortTo;
sortTo.delete();
file.renameTo(sortTo);
} else {
println "File already exists. Skipping: " + sortTo;
}
} else {
file.renameTo(sortTo);
}
}
}
}
}
}
Configuration
There are 6 predefined resolutions. Feel free to edit the following line to add more resolutions:
def resolutions = [..,'1': 'mdpi',..];
Many graphic editors output files in the format name@1x
or name_1x
. If your designer has another file naming convention you can add it in this line:
def tags = ['@#x', '_#x'];
The #
character will be replaced by the resolution factor.