It’s a lot of work to provide icons for mobile devices, because of the large number of different formfactors and screen pixel-densities.
Android is using the following set of values:
Name | DPI | Scaling Factor | Default Icon Size |
ldpi (low) | ~120dpi | 0.7 | 18 x 18 |
mdpi (medium) | ~160dpi | 1.0 | 24 x 24 |
hdpi (high) | ~240dpi | 1.5 | 36 x 36 |
xhdpi (extra-high) | ~320dpi | 2.0 | 48 x 48 |
xxhdpi (extra-extra-high) | ~480dpi | 3.0 | 72 x 72 |
xxxhdpi (extra-extra-extra-high) | ~640dpi | 4.0 | 96 x 96 |
Source: http://developer.android.com/guide/practices/screens_support.html
To ensure that you get sharp icon shapes you need to provide different icon-files (usually png-files) for each DPI class.
Another approach is to make use of Scaleable Vectro Graphics (SVG).
It is good idea to create the SVG file with the default size of the unscaled icon (24 x 24 pixel at Android). As an example I have crated a cup icon with Adobe Illustrator.
Make sure that the horizontal and vertical lines of the shape are aligned to the pixel-grid. This will ensure, that the shape is sharp, when it is rasterized to the default size.
Then create a new file for the icon-control. I called it “IconSVG.qml”. I have added an ColorOverlay to provide the ability to colorize the icon.
import QtQuick 2.0
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
Image {
id: root
property alias color: colorOverlay.color
smooth: true
ColorOverlay {
id: colorOverlay
anchors.fill: root
source: root
color: "#000000"
}
}
Now you can use it like this:
Row {
spacing: 10
IconSVG {
source: "cup.svg"
color: "#000000"
}
IconSVG {
source: "cup.svg"
color: "#0092CC"
}
IconSVG {
source: "cup.svg"
color: "#FF3333"
}
IconSVG {
source: "cup.svg"
color: "#DCD427"
}
IconSVG {
source: "cup.svg"
color: "#779933"
}
}
The result should look like this on a desktop PC:
Lets scale-up the application to simulate a device with higher DPI, for example 480dpi, which means a scaling factor of 3. You can easily do this by adding the following line inside the “main.cpp” file:
qputenv("QT_SCALE_FACTOR", QByteArray("3")); // for testing purpose only. Remove it later
The result is:
As expected, the SVG gets rasterized to the default size of 24 x 24 pixels and then scaled up to 96 x 96 pixels, causing an ugly blurry shape. That’s not exactly what we want.
Modify the “IconSVG.qml” file like this:
import QtQuick 2.0
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
Image {
id: root
smooth: true
property alias color: colorOverlay.color
property int size: 24 // default
sourceSize.width: size
sourceSize.height: size
ColorOverlay {
id: colorOverlay
anchors.fill: root
source: root
color: "#000000"
}
}
When the “sourceSize” property is set explicitly it will trigger a new rendering of the SVG to the declared size and – magically – qt will even consider the scaling-factor of the application and multiplies it by default. In the example you just need to set this value to 24, the default size of the icon and you get a perfect 96 x 96 image:
As you can see, the icons are sharp and nicely colored.