Android Adaptive icon foreground always too big - android

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.

Related

Splash screen animation requirements - Icon Dimensions

I am using Splash screen compat library.
I am using an AVD XML (pic 1 below). When I run on android 12 (on emulator via launchbar), I see some animation happening , but my icon is clipped (as in pic 2).
.
Referring Dimensions in documentation here , it says
The icon area must be 432 dp
The inner two-thirds of the image is
visible on the launcher icon, and must be 288 dp
Point a, I was able to correct in the xml by specifying
android:width="432dp"
android:height="432dp"
But Point b, I am unable to understand. What exactly needs to be 288 dp.
I also looked at the xml given in example starter kit .
<vector
android:width="432dp"
android:height="432dp"
android:viewportWidth="432"
android:viewportHeight="432">
I don't see a 288 value anywhere.
What am I missing ?
My AVD xml looks like follows :
<vector
android:name="vector"
android:width="432dp"
android:height="432dp"
android:viewportWidth="192"
android:viewportHeight="192">
<path....
I found my mistake.
Viewport dimensions need to be 288 (as mentioned in documentation of splash screen icon) . This displays perfectly in both android 11 and 12.
android:name="vector"
android:width="432dp"
android:height="432dp"
android:viewportWidth="288"
android:viewportHeight="288">

Using the right dpi on vector icons

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 ...

Android XML drawables scaling

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
}

9 Patch png not working correctly for background

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

Android splash screen image sizes to fit all devices

I have a full screen PNG I want to display on splash. Only one error there, and I have no idea
what size to put in every drawable folder (ldpi, mdpi, hdpi, and xhdpi). My application is supposed to run good and beautiful on all phones and tablets. What sizes (in pixels) should I create so the splash displays nice on all screens?
Disclaimer
This answer is from 2013 and is seriously outdated. As of Android 3.2 there are now 6 groups of screen density. This answer will be updated as soon as I am able, but with no ETA. Refer to the official documentation for all the densities at the moment (although information on specific pixel sizes is as always hard to find).
Here's the tl/dr version
Create 4 images, one for each screen density:
xlarge (xhdpi): 640x960
large (hdpi): 480x800
medium (mdpi): 320x480
small (ldpi): 240x320
Read 9-patch image introduction in Android Developer Guide
Design images that have areas that can be safely stretched without compromising the end result
With this, Android will select the appropriate file for the device's image density, then it will stretch the image according to the 9-patch standard.
end of tl;dr. Full post ahead
I am answering in respect to the design-related aspect of the question. I am not a developer, so I won't be able to provide code for implementing many of the solutions provided. Alas, my intent is to help designers who are as lost as I was when I helped develop my first Android App.
Fitting all sizes
With Android, companies can develop their mobile phones and tables of almost any size, with almost any resolution they want. Because of that, there is no "right image size" for a splash screen, as there are no fixed screen resolutions. That poses a problem for people that want to implement a splash screen.
Do your users really want to see a splash screen?
(On a side note, splash screens are somewhat discouraged among the usability guys. It is argued that the user already knows what app he tapped on, and branding your image with a splash screen is not necessary, as it only interrupts the user experience with an "ad". It should be used, however, in applications that require some considerable loading when initialized (5s+), including games and such, so that the user is not stuck wondering if the app crashed or not)
Screen density; 4 classes
So, given so many different screen resolutions in the phones on the market, Google implemented some alternatives and nifty solutions that can help. The first thing you have to know is that Android separates ALL screens into 4 distinct screen densities:
Low Density (ldpi ~ 120dpi)
Medium Density (mdpi ~ 160dpi)
High Density (hdpi ~ 240dpi)
Extra-High Density (xhdpi ~ 320dpi)
(These dpi values are approximations, since custom built devices will have varying dpi values)
What you (if you're a designer) need to know from this is that Android basically chooses from 4 images to display, depending on the device. So you basically have to design 4 different images (although more can be developed for different formats such as widescreen, portrait/landscape mode, etc).
With that in mind know this: unless you design a screen for every single resolution that is used in Android, your image will stretch to fit screen size. And unless your image is basically a gradient or blur, you'll get some undesired distortion with the stretching. So you have basically two options: create an image for each screen size/density combination, or create four 9-patch images.
The hardest solution is to design a different splash screen for every single resolution. You can start by following the resolutions in the table at the end of this page (there are more. Example: 960 x 720 is not listed there). And assuming you have some small detail in the image, such as small text, you have to design more than one screen for each resolution. For example, a 480x800 image being displayed in a medium screen might look ok, but on a smaller screen (with higher density/dpi) the logo might become too small, or some text might become unreadable.
9-patch image
The other solution is to create a 9-patch image. It is basically a 1-pixel-transparent-border around your image, and by drawing black pixels in the top and left area of this border you can define which portions of your image will be allowed to stretch. I won't go into the details of how 9-patch images work but, in short, the pixels that align to the markings in the top and left area are the pixels that will be repeated to stretch the image.
A few ground rules
You can make these images in photoshop (or any image editing software that can accurately create transparent pngs).
The 1-pixel border has to be FULL TRANSPARENT.
The 1-pixel transparent border has to be all around your image, not just top and left.
you can only draw black (#000000) pixels in this area.
The top and left borders (which define the image stretching) can only have one dot (1px x 1px), two dots (both 1px x 1px) or ONE continuous line (width x 1px or 1px x height).
If you choose to use 2 dots, the image will be expanded proportionally (so each dot will take turns expanding until the final width/height is achieved)
The 1px border has to be in addition to the intended base file dimensions. So a 100x100 9-patch image has to actually have 102x102 (100x100 +1px on top, bottom, left and right)
9-patch images have to end with *.9.png
So you can place 1 dot on either side of your logo (in the top border), and 1 dot above and below it (on the left border), and these marked rows and columns will be the only pixels to stretch.
Example
Here's a 9-patch image, 102x102px (100x100 final size, for app purposes):
Here's a 200% zoom of the same image:
Notice the 1px marks on top and left saying which rows/columns will expand.
Here's what this image would look like in 100x100 inside the app:
And here's what it would like if expanded to 460x140:
One last thing to consider. These images might look fine on your monitor screen and on most mobiles, but if the device has a very high image density (dpi), the image would look too small. Probably still legible, but on a tablet with 1920x1200 resolution, the image would appear as a very small square in the middle. So what's the solution? Design 4 different 9-patch launcher images, each for a different density set. To ensure that no shrinking will occur, you should design in the lowest common resolution for each density category. Shrinking is undesirable here because 9-patch only accounts for stretching, so in a shrinking process small text and other elements might lose legibility.
Here's a list of the smallest, most common resolutions for each density category:
xlarge (xhdpi): 640x960
large (hdpi): 480x800
medium (mdpi): 320x480
small (ldpi): 240x320
So design four splash screens in the above resolutions, expand the images, putting a 1px transparent border around the canvas, and mark which rows/columns will be stretchable. Keep in mind these images will be used for ANY device in the density category, so your ldpi image (240 x 320) might be stretched to 1024x600 on an extra large tablet with small image density (~120 dpi). So 9-patch is the best solution for the stretching, as long as you don't want a photo or complicated graphics for a splash screen (keep in mind these limitations as you create the design).
Again, the only way for this stretching not to happen is to design one screen each resolution (or one for each resolution-density combination, if you want to avoid images becoming too small/big on high/low density devices), or to tell the image not to stretch and have a background color appear wherever stretching would occur (also remember that a specific color rendered by the Android engine will probably look different from the same specific color rendered by photoshop, because of color profiles).
I hope this made any sense.
PORTRAIT MODE
MDPI is 320x480 dp = 320x480px (1x)
LDPI is 0.75 x MDPI = 240x360px
HDPI is 1.5 x MDPI = 480x720px
XHDPI is 2 x MDPI = 640x960px
XXHDPI is 3 x MDPI = 960x1440px
XXXHDPI is 4 x MDPI = 1280x1920px
LANDSCAPE MODE
MDPI is 480x320 dp = 480x320px (1x)
LDPI is 0.75 x MDPI = 360x240px
HDPI is 1.5 x MDPI = 720x480px
XHDPI is 2 x MDPI = 960x640px
XXHDPI is 3 x MDPI = 1440x960px
XXXHDPI is 4 x MDPI = 1920x1280px
EDIT:
I would suggest to use Lottie for splash screen if you are reading this in 2019+
PORTRAIT
LDPI: 200x320px
MDPI: 320x480px
HDPI: 480x800px
XHDPI: 720px1280px
LANDSCAPE
LDPI: 320x200px
MDPI: 480x320px
HDPI: 800x480px
XHDPI: 1280x720px
I have searched the best and the simplest answer to make 9-patch image. Now to make the 9 patch image is the easiest task.
From https://romannurik.github.io/AndroidAssetStudio/index.html you can make a 9-patch image for all the resolutions - XHDPI,HDPI,MDPI,LDPI in just one click.
Using PNG is not such a good idea. Actually it's costly as far as performance is concerned.
You can use drawable XML files, for example, Facebook's background.
This will help you to smooth and speed up your performance, and for the logo use .9 patch images.
Density buckets
LDPI 120dpi .75x
MDPI 160dpi 1x
HDPI 240dpi 1.5x
XHDPI 320dpi 2x
XXHDPI 480dpi 3x
XXXHDPI 640dpi 4x
px / dp = dpi / 160 dpi
In my case, I used list drawable in style.xml. With layer list drawable, you have just needed one png for all screen size.
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">#drawable/flash_screen</item>
<item name="android:windowTranslucentStatus" tools:ignore="NewApi">true</item>
</style>
and flash_screen.xml in drawable folder.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/white"></item>
<item>
<bitmap android:src="#drawable/background_noizi" android:gravity="center"></bitmap>
</item>
</layer-list>
"background_noizi" is a png file in the drawable folder.
I hope this helps.
Some time ago i created an excel file with supported dimensions
Hope this will be helpful for somebody
To be honest i lost the idea, but it refers another screen feature as size (not only density)
https://developer.android.com/guide/practices/screens_support.html
Please inform me if there are some mistakes
Link1: dimensions.xlsx
Link2: dimensions.xlsx
Edited solution that will make your SplashScreen look great on all APIs including API21 to API23
If you are only targeting APIs24+ you can simply scale down your vector drawable directly in its xml file like so:
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="640"
android:viewportHeight="640"
android:width="240dp"
android:height="240dp">
<path
android:pathData="M320.96 55.9L477.14 345L161.67 345L320.96 55.9Z"
android:strokeColor="#292929"
android:strokeWidth="24" />
</vector>
in the code above I am rescaling a drawable I drew on a 640x640 canvas to be 240x240. then i just put it in my splash screen drawable like so and it works great:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque"
android:paddingBottom="20dp" android:paddingRight="20dp" android:paddingLeft="20dp" android:paddingTop="20dp">
<!-- The background color, preferably the same as your normal theme -->
<item>
<shape>
<size android:height="120dp" android:width="120dp"/>
<solid android:color="#android:color/white"/>
</shape>
</item>
<!-- Your product logo - 144dp color version of your app icon -->
<item
android:drawable="#drawable/logo_vect"
android:gravity="center">
</item>
</layer-list>
my code is actually only drawing the triangle in the picture at the bottom but here you see what you can achieve with this. Resolution is finally great as opposed to the pixelated edges I was getting when using bitmap. so use a vector drawable by all means (there is a site called vectr that I used to create mine without the hasle of downloading specialized software).
EDIT in order to make it work also on API21-22-23
While the solution above works for devices runing API24+ I got really disappointed after installing my app a device running API22. I noticed that the splashscreen was again trying to fill the entire view and looking like shit. After tearing my eyebrows out for half a day I finally brute-forced a solution by sheer willpower.
you need to create a second file named exactly like the splashscreen xml (lets say splash_screen.xml) and place it into 2 folders called drawable-v22 and drawable-v21 that you will create in the res/ folder (in order to see them you have to change your project view from Android to Project). This serves to tell your phone to redirect to files placed in those folders whenever the relevant device runs an API corresponding to the -vXX suffix in the drawable folder, see this link. place the following code in the Layer-list of the splash_screen.xml file that you create in these folders:
<item>
<shape>
<size android:height="120dp" android:width="120dp"/>
<solid android:color="#android:color/white"/>
</shape>
</item>
<!-- Your product logo - 144dp color version of your app icon -->
<item android:gravity="center">
<bitmap android:gravity="center"
android:src="logo_vect"/>
</item>
For some reason for these APIs you have to wrap your drawable in a bitmap in order to make it work and jet the final result looks the same. The issue is that you have to use the aproach with the aditional drawable folders as the second version of the splash_screen.xml file will lead to your splash screen not being shown at all on devices running APIs higher than 23. You might also have to place the first version of the splash_screen.xml into drawable-v24 as android defaults to the closest drawable-vXX folder it can find for resources. hope this helps
** If you are looking for screen details for all kind of major devices **
go to material.io
Based off this answer from Lucas Cerro I calculated the dimensions using the ratios in the Android docs, using the baseline in the answer. I hope this helps someone else coming to this post!
xxxlarge (xxxhdpi): 1280x1920 (4.0x)
xxlarge (xxhdpi): 960x1440 (3.0x)
xlarge (xhdpi): 640x960 (2.0x)
large (hdpi): 480x800 (1.5x)
medium (mdpi): 320x480 (1.0x baseline)
small (ldpi): 240x320 (0.75x) 

Categories

Resources