dkanada / frost

Icon Pack for Android Devices
GNU General Public License v3.0
164 stars 76 forks source link

use vector (android vector drawable xml, avdx) directly instead of raster (png) icons #26

Open conrad-heimbold opened 7 years ago

conrad-heimbold commented 7 years ago

Since API level 21, Android can handle vector drawables: https://developer.android.com/reference/android/graphics/drawable/VectorDrawable.html

Here are some information: https://androidbycode.wordpress.com/2015/03/18/vector-graphics-in-android-converting-svg-to-vectordrawable/

Simple SVG can directly be transformed into avdx. Do we already have a script for that? If not, this is what I found with google:

I don't know if Android Studio also has the ability to convert svg to android vector graphics... The Android SDK has native support for vector graphics with the class

android.graphics.drawable.VectorDrawable

conrad-heimbold commented 7 years ago

Android does not support fill-rule:evenodd attributes, matrix / transform attributes and the scientific e-notation (at least not before API level 24). Before we can do this step, we first have to fix the issues from #27 .

ghost commented 7 years ago

Does this mean the app will not work on any API below 21?

conrad-heimbold commented 7 years ago

There is official documentation on how to achieve backward compatibility: https://developer.android.com/guide/topics/graphics/vector-drawable-resources.html#vector-drawables-backward-solution

conrad-heimbold commented 7 years ago

@ikocevski : backward compatibility shouldn't be too difficult, don't worry.

ghost commented 7 years ago

Alright, because I'm still at 4.4 :/

conrad-heimbold commented 7 years ago

Alright, because I'm still at 4.4 :/

@ikocevski : No Cyanogenmod or LineageOS for your device? Have a look here:

You have to know the code name for your device to choose the right file. You can find out the code name by looking in Wikipedia for your device; or by going into settings -> about phone -> build number or android version (which usually contains the code name) .

If there is nothing, you poor...

conrad-heimbold commented 7 years ago

It is really annoying for android developers to always keep backward compatibility, just because the

ghost commented 7 years ago

@conrad-heimbold Oh believe me I'm not lazy or uninformed. I got CM on it but the latest I can get is 4.4.4. I should just buy a new phone and stop bothering with this one. I'm considering anything from Samsung's S line since they officially support every one of those. They are a bit pricey though... If you find anything above 4.4 let me know though, it's a Samsung SM-G313HN (codename: vivaltonfc3g). The thing is ancient LOL.

conrad-heimbold commented 7 years ago

I own a Moto G falcon from 2013, which still has got very good support from CyanogenMod and LineageOS. My one runs CyanogenMod 13.0 , but there is also LineageOS 14 available as nightlies (just like all other LineageOS devices, only nightlies, so kind of "usual"). I can only recommend it, now it should cost less than 100€! What's even better: repairing it and getting spare parts (e.g. from fixez.com ) is also quite easy. The only limitation of the Moto G: it only has 1GB of RAM . As we all know, Android is very RAM-hungry. So don't expect too much multi-tasking...

EDIT: What a pity, Moto G 1st generation (codename: falcon) seems to be sold out because of popularity... Couldn't find any offer on Amazon and only one offer on Ebay. Maybe you can look for other Moto devices; support for these seems to be good.

conrad-heimbold commented 7 years ago

One example for an app, which only uses android vector XML data for its icon (no png icon AT ALL!), is the SystemUI app at least on CyanogenMod 13. How to get it:

$ cp /system/priv-app/SystemUI/SystemUI.apk ~
$ cd  ~
$ mkdir SystemUI
$ unzip SystemUI.apk -d SystemUI
$ cd SystemUI/res/drawable-nodpi-v4/
# Now, convert the Android binary XML to human-readable XML with AXMLPrinter2.jar (should be somewhere in your $ANDROID_SDK ): 
$ java -jar $ANDROID_SDK/AXMLPrinter2.jar icon.xml > icon.real.xml

The android vector app icon now is icon.real.xml

dkanada commented 7 years ago

Is the format specific to Android? I have seen the files in OpenLauncher, thought they were some weird type of vector image but didn't look too far into it. I wonder why they didn't just use svg files.

conrad-heimbold commented 7 years ago

@dkanada: quote from "phil" and "Bernard" in the second link:

phil:

[...] What a bad idea from Google to introduce one more new format instead of supporting SVG ( standard ) [...]

Bernard:

@phil: “Yet another format” I also thought that too at first. At the same time, SVG format is full of issues to start with. I think Android started with a clean slate so they can have a robust solution without introducing tons of code and complications. [...] SVG is the mess. [...] .

SVG also needs tons of RAM for "compiling" (or whatever you call it) because of the many possibilities. Limiting them maybe decreases RAM usage. After all, our screen still consist of pixels, so the graphics have to be rasterized at one point

ghost commented 7 years ago

Vectors (in any format) are still nice to have. It's like keeping music in a lossless format, both can be converted to a "lossy" state whenever needed and we still have the full quality of the original files.

conrad-heimbold commented 7 years ago

one more benefit if we use android vector drawables directly in the app: the app will become much smaller. Cheap smartphones often have got only 8 (total) - 4 (system / pre-installed apps) = 4 GB = 4000 MB of free storage. If we use png's instead of svg/vector drawables, the app will be (in the end) at least 40 MB big, so already 40 / 4000 = 0.01 = 1% of all the storage is taken only by the icon pack app. This is the state ATM, but as we are already adding more and more icons, this number will increase rapidly! APK file sizes for ICEcons: version 2.6 by 1C3: 47.6 MB version 2.7 by 1C3: 47.9 MB version 2.8 by 1C3: 39.4 MB version 1.0 by dkanada: 39.7 MB version 1.1 by dkanada: 39.8 MB version 1.2 by dkanada: 40.1 MB EDIT: 2017-07-09 - Most of the storage space seems to be taken by the wallpapers, not the png icons.

dkanada commented 7 years ago

Will we lose compatibility with older versions of android if we make the switch? As much as a I hate having to make apps backwards compatible, I think it is necessary in such a fragmented market for phones. Maybe if the cutoff version is low enough.

conrad-heimbold commented 7 years ago

Clear-cut option

We offer two versions of the app:

Complicated option

We only offer one app, which also offers backwards compatibility via png's until Android 2.1; but not for xxxhdpi, xxdpi devices; only xhdpi, mdpi and ldpi devices get backward compatibility. Devices with larger screens (xxhdpi. xxxhdpi) are typically more new and popular and usually have got a newer android version via CyanogenMod / LineageOS / nightlies. ~~If we can leave away the xxxhdpi and xxhdpi icons, our app should also become smaller. Please tell me if my assumption is true / applicable and look for counterexamples~~ EDIT: no benefit with this option.

easiest-to-explain option

We only offer one app which includes both android vector xml and png's for all kinds of display sizes and which is backwards compatible until Android 2.1. Disadvantage: the app will become even bigger, probably around 50MB. Maintaining the icon generation process for png's and android vector xml in parallel will become tedious.

ghost commented 7 years ago

~30% of Android's market share belongs to versions below 5.0 (as of May 2017). Consider that.

The "Simple option" is nice, IMO but will we be able to manage two separate projects/branches? The "Complicated option" is okay if feasible, I mean, if I try to install an app that requires any API above the one that I currently have then it just pops up a parse error. Also how easy will this be to maintain, just delete the pngs for these devices? If not, I'm not a fan. The "easiest-to-explain option" is pointless. Just pointless.

I say we just keep the app as it is and keep this idea for later on. Maybe after 2018? Going to vector xml fully is the best option but if we don't have any other options for backward-compatibility this isn't good.

conrad-heimbold commented 7 years ago

I would really like to make a fork (separate app), implementing option 1 (separate app with android vector XML), if I have enough time at one point in the future to learn Android coding... You (@dkanada, @ikocevski) don't seem to be much interested in such an improvement...

ghost commented 7 years ago

New statistics were published on xda and they say that devices that run on Android below 5.0 are at 25.4% of the market. That's a very quick shift in market share in such a short time, but it's still a lot of devices left unsupported. I don't see why the hurry here. Let's just make this switch later on.

dkanada commented 7 years ago

I was suprised the apk took that much space since the icons aren't that large to begin with, so I ran a size check on all the folders in res and you can see the results here.

1.1M drawable-hdpi/ 1.1M drawable-mdpi/ 38M drawable-nodpi/ 1.1M drawable-xhdpi/ 1.2M drawable-xxhdpi/ 2.6M drawable-xxxhdpi/ 8.0K mipmap-xxxhdpi/ 28K values/ 68K xml/

It seems the major issue here is the nodpi folder. That folder contains icons for the preview activity in the app and all twelve wallpapers that get bundled with the app. I might be able to remove the icons in there to reduce the size of the app slightly, but most of the space in that folder is taken up by the 4K wallpapers that @1C3 included with the app.

I actually think that the vector drawables would be great to try out, but I think the issue isn't really the png files here, it is the wallpaper images. Removing those would drop the apk size to somewhere around 8MB right now. Another option is just scaling the wallpapers to fit HD screens rather than 4K screens, although I am not sure of the size reduction in that case.

ghost commented 7 years ago

@conrad-heimbold I was just working on the language pack for AnySoftKeyboard and there's an option to put a drawable to show up in the notification bar. Originally the devs say to put a png file for this but the icon wasn't as sharp as I expected, the original English tag was much sharper. Then I realized maybe it's a Vector Drawable? If so, how does it work on Android 4.4.4 without crashing? It just shows the thing perfectly fine and just to check I made an SVG, converted it to Android Vector Drawable and built the app. Guess what... it really does work.

Is this some kind of magic coding that AnySoftKeyboard has or is it just the launcher icons we're talking about not being compatible with Android below 5.0? I'm confused :S

conrad-heimbold commented 7 years ago

@ikocevski : Sorry, I really don't know. Are you sure Android Studio did not convert the avdx (android vector drawable xml) to png before building the apk?

ghost commented 7 years ago

How can I find out? Edit, yes, they were converted to png.

ghost commented 7 years ago

Found them in \build\generated\res\pngs\debug\ and yes also in the apk's res directory.

ghost commented 7 years ago

I see how this works now. There's an xml drawable for all sizes of screens (no dpi) but if the minimum API is set to lower than v21 Android Studio converts that xml file to png for specific screen sizes (ldpi, mdpi, hdpi...)

If the png is sized properly for the screen size then it's as sharp as the vector by some logic AND if there are pngs for that size of screen it will default to them instead of re-rasterizing the xmls also by some logic. I don't know if it works like this, correct me if I'm wrong.

If I'm correct though then the only way to properly implement vector icons is not to have any pngs in the drawables folders. Which means it's the best to just do another branch of the project (or fork) that implements only vectors. Either that or wait a bit for the market share of Android <5.0 to lower and then completely move to vectors just as I said before.

conrad-heimbold commented 7 years ago

I think you can also do "flavours" or whatever you call it of the same app inside Android Studio, called e.g. "main", " beta", "production" or "development". Maybe that's also an option to maintain the app for different android version?

ghost commented 7 years ago

TBH I can see Android Studio integrates with git, so there wouldn't be any issues with keeping another app on a different branch. git checkout and move on but it's still more work to convert the icons from svg to xml.

Have you actually tried offline to convert the icons in /icons/*.svg to xml, put them in /src/main/res/drawables/ build it like that and remove the png drawables? Try it and see if there's any benefit at all. Otherwise we'd be doing additional work for nothing.

conrad-heimbold commented 7 years ago

One possible real benefit of xml would be: you could specify the color of the icons inside the icon pack app! Not just white, but any color you want. Wouldn't that be really cool? That's the next barrier to break in terms of customization! I am sure this is possible, however it would probably need some hacking / tweaking

This however will only work, if the vector icons are used; not the png ones (you can't edit pngs on-the-fly).

conrad-heimbold commented 7 years ago

example what I would like to achieve: icons_svg.zip . Unzip first, then open the SVG files inside a browser, not in the default viewer app (they don't support external css file sheets).

ghost commented 7 years ago

Why not implement the XML drawables now and make the additional features Android 5> only. Is that possible? Like, you wanted the icons to change color, so all the changes will be applied to the drawable-nodpi folder and the regular PNG will remain the same. We could just put a warning that pops out before someone in the app decides to change the color. Something like: Color changes won't apply on devices with Android API below version 21 (KitKat and older)

Now the question is, can you force these devices that support AVDX to use only that icon instead of defaulting to the raster ones?