I'm struggling to understand the usage pattern behind XML drawables.
Some sources say that they should automatically scale based on resolution. My experience says different.
For example, using absolute size in a vector like this:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp" ... />
Will actually display this shape in size 24dp in all resolutions. I do not observe any automatic scaling happening at all, e.g. it looks tiny on tablets resolutions.
So I declared various sizes in values/dimens.xml, and added it to the shape like this:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="#dimen/status_icon_size"
android:height="#dimen/status_icon_size" ... />
which sort of fixed the original issue, but then it fails to build after adding min-sdk = 19 (Android 4.4). When generating bitmaps from these vectors the compiler seems to have problem using values from dimens.xml:
Error:Error: Width (0) and height (0) cannot be <= 0
I want to avoid having multiple icon.xml in all possible drawables_w***dp like with dimens.xml. I already have a bunch of dimens.xml. Isn't the whole purpose of vector icons to have easy scaleability?
Q: Is there a way to make a properly scalable icon which works for all screen resolutions with just one instance of the XML file in /res/drawable?
To avoid this error Error:Error: Width (0) and height (0) cannot be <= 0
Add this string to app build.gradle:
defaultConfig {
...
vectorDrawables.useSupportLibrary = true
}
Related
I have a problem and I don't know how to solve it.
I am trying to make an adaptive android app icon. That's the code for it:
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="#drawable/launcher_backg" />
<foreground android:drawable="#drawable/logo" />
</adaptive-icon>
That's what it looks like:
As you can see, the foreground is way too big. I don't want that, and I don't know how to fix it. I had a workaround, where I just scaled the foreground until it was small enough. The problem then is, that I don't know what the best size is and all, and I'm sure, there is a better solution.
The foreground is a png and the background a vector graphic.
How can I make the foreground to be the perfect size for an android app icon.
As you can tell from this reference the following sizes need to be provided:
In Android 7.1 (API level 25) and earlier, launcher icons were sized at 48 x 48 dp. You must now size your icon layers using the following guidelines:
Both layers must be sized at 108 x 108 dp.
The inner 72 x 72 dp of the icon appears within the masked viewport.
The system reserves the outer 18 dp on each of the 4 sides to create
interesting visual effects, such as parallax or pulsing.
Is it possible to get correctly scaled item drawable in android layer-list item?
I prepared something like this:
bg.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/splash_bg" />
<item
android:gravity="center"
android:drawable="#drawable/logo_white">
</item>
</layer-list>
The sizes for drawable/logo_white vector has: 200dp width and 100dp height. It looks nice for small devices, but on tablet this logo is too small.
Is it possible to make it responsive for bigger screens?
Many thanks for help.
You can use attribute width and height in API level 23 and higher:
<item
android:width="#dimen/your_size" android:height="#dimen/your_size"
android:drawable="#drawable/logo_white"/>
And create different dimens files, for normal phones, tab, etc
Android has multiple folder system for multiple resolutions.
layout-hdpi,
layout-xhdpi, etc.
and same goes for drawable folder too. So by implementing same filename but edited xml based on dimension for different folder you can make in responsive. You might find other different technique for this.
I'm new on android studio and planning to design an app for tablets and phones. Therefore my app will be mostly used on normal and large screens.
Which dpi is best for my vector icons ?
Should I make different dpi versions of the same icon for multiple screen support ?
Why only making the icons wrap_content doesnt support multiple screen sizes. I thought vector images doesnt get blurred when they are distorted.
The "dpi" for vector icons is meaningless. Vector icons are DPI independent. That's the whole point of them. It doesn't matter what size you design them at. It only makes a difference what size you draw (render) them at at run time. The bigger the size it is displayed at, the more pixels have to be calculated and drawn.
That's what the second paragraph in #muhammad-younas answer (which is from this Colt McAnlis blog) is trying to say.
I use InkScape for editing and save my SVG files (vector images). In theory, it scales well for any size. In theory...
In Android Studio I use New, Vector Asset, and I select the SVG file and it generates a XML file, below drawables folder, under res folder. But sometimes, without any explanation, the image was blurred in my phone (Not blurred in the Android Studio preview). It's crazy.
I've tried everything, and just one action has solved my problem:
I've decided to change XML file directly in Android Studio. I read something about width and height specs (image size) vs viewportWidth and viewportHeight (image real size in the cell phone)
So I've decided scaled up the first width and height pair
For instance, one blurred image has:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="6.415605dp"
android:height="5.33568dp"
android:viewportWidth="6.415605"
android:viewportHeight="5.33568">
....
</vector>
I've set in my head the width = 25dp, so I've made 25 / 6.415605 = 3.89675. So I've multiplied both numbers in the first pair by 3.89675. So I've got new values for width and height.
It's just a random guess. The important is to make width and height much bigger than viewport width and viewport height, preserving the proportions.
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="25dp"
android:height="20.7915dp"
android:viewportWidth="6.415605"
android:viewportHeight="5.33568">
....
</vector>
It works like a charm ...
The Problem
I have an ImageView in my XML like that:
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/ic_person_add"
android:alpha="0.87" />
The ic_person_add is the normal Material design Vectoricon.
On my Nexus 5 (Android 6), the icon scales beautiful and is really sharp:
On a Note 2 (Android 4.4) however, the icon gets really pixelated and ugly:
How do I get the ImageView (with a Vector as src) sharp on every device? Preferably with an only xml solution.
I already found:
Adding android:adjustViewBounds="true" -> did nothing
ImageView images seem pixelated and low quality -> Doesn't apply to vector
Setting BitmapFactory.inscaled=false -> doesn't work with only xml and I didn't know where to put this in a custom ImageView class.
The real problem wasn't the DPI of the Note 2, it was its Android Version.
The Link Melllvar posted states:
Once you have a vectorDrawable image in your res/drawable, the Gradle plugin will automatically generate raster PNG images for API level 20 and below during build time
So my Android 6 device really had a Vectorgraphic as source for the ImageView so it managed to scale it up flawlessly.
For the Note 2 (running on an older than Android 5 OS) Android Studio automatically converted the Vectorgraphic in my Drawables Folder to a PNG.
You can change the size of the converted PNG in the VectorXML by changing the
android:height android:width
to the size in dp your vectorgraphic needs to be displayed on pre API 20 devices. So in my Case (maximum of 100dp) I had to change the Values to:
<vector android:height="100dp" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="100dp">
The Nexus 5 density bucket is xxhdpi, while the Note 2's (based on this) is xhdpi. This suggests that your xxhdpi bitmap is sized properly (or is, at least, at or above the required size), while xhdpi isn't.
If you're using the automatic conversion provided by the recent versions of Android studio, you may want to try rasterizing the vector image manually to see if this fixes the issue.
If you're using raster graphics, you may want to add some visual element to each density variant to get an idea which one is actually being used.
I'm trying to create a background image for my app that will look sharp on all resolutions/orientations.
I'm new to android development, but I understand the easiest way to achieve this is to use 9 patch images. I thought I understood how they worked, but I can't get it to work.
I've created a background image # 768 x 1280 which is the resolution of my Nexus 4. When I don't 9 patch it and view it on my device, it looks fine (obviously, because the resolution/orientation matches the device's):
So it looks nice and sharp.
But then I add the patches onto the image using the drawer9patch.bat file and rename the file to '.9.png' and this is the result:
Knackered!
The strange thing is: in the preview pane in the right hand side of the draw9patch tool it all looks fine....
I've also tried making the image at a smaller resolution, but the logo & text don't look sharp; they look pixelated...
I feel there must be some vital piece of the puzzle I'm missing? The area I've defined as content is being stretched?
Here is my layout code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/my_background_image_patched"
android:padding="0px">
<!-- Login controls here --->
</RelativeLayout>
Here is my 9 patch image (which is located to the 'drawable' folder):
OK, I tinkered with your 9 patch.
I must say it was poorly designed (72 dpi, while it should really be 320 dpi).
So, I redesigned it (you can see I moved the black pixels) and saved it to 320 dpi (in the drawable-xhdpi folder).
It seems it scaled well at ldpi and mdpi screens (so, I guess it will also scale well at hdpi):
The patch I used is this:
Try to generate Nine-Patch using this Nine-patch Generator allows you to quickly generate simple nine-patches at different screen densities, based on the specified source artwork