How to verify (digital) pixel-perfect development in Android? - android

tl;dr How do I convert pixel measurements on one device to pixel measurements on another?
I've designed an Android app with all the screens measuring 720x1280 px. I've assumed this is at 2.0 xhdpi meaning digital-pixel dimensions of 360x640 dp.
Now in QA I've found a few inconsistencies on my Nexus 5x, taken screenshots, and pulled them into Photoshop to confirm/measure the errors. The Nexus 5x is 1080x1920 px, but is at 2.6 xxhdpi which converts to 411x731 dp.
Won't just a simple scale fail?
It's not as simple as pulling the Nexus (1080 width) screenshots into Photoshop and scaling them to width 720, right? That doesn't account for pixel densities.
Said another way. If a square is 100px (50dp) on my #2x design, how large should I expect it to be on the Nexus screenshot?
Helpful links
Android Docs, especially the part about Supporting Multiple
Screens
Google's Device Metrics

There are multiple questions/thoughts in your post.
To start:
How do I convert pixel measurements on one device to pixel
measurements on another?
And:
I've designed an Android app with all the screens measuring 720x1280
px.
I'm going to assume you mean that you made some digital images/ux documents at 720x1280 and now are building out the code/loading images for your app and have run into problems because different devices are behaving in an unexpected way? Correct me if this is inaccurate.
Designing for Android, and mobile in general, is at least to some extent about asking yourself what you want the user to experience, and how to accomplish that within the framework's rules for building an interface.
Google states that when dealing with multiple devices you should aim for "density independence":
Your application achieves "density independence" when it preserves the
physical size (from the user's point of view) of user interface
elements when displayed on screens with different densities.
The image below represents "bad" design (doesn't take into account dp)
The image below represents good "density independent" design:
http://developer.android.com/guide/practices/screens_support.html#density-independence
In other words, if taking into account density independence when designing and building your app, the user should see images and/or views in a consistent way across devices. Verifying images and views on different devices should not be done in Photoshop or similar, it should be accomplished in the emulator provided in Android Studio and/or on multiple physical devices with various OS versions and/or screen sizes (as they are available to you).
Another thing to keep in mind:
You asked:
Said another way. If a square is 100px (50dp) on my #2x design, how
large should I expect it to be on the Nexus screenshot?
Go to the Google Device Metrics page:
Click on Nexus 5x, and look at the device info from the slide-in panel:
According to this info, the Google Nexus 5x is 424px/in i.e. 424dpi
Use the equation px = 50dp * (dpi / 160)
px = 132.5
It is valuable to also give a real-life example of how to calculate pixel and dp sizes when using a specific device, and hope that this helps you get to the next step and answer the question above in the future.
Let’s say we have some images we want to fit "perfectly" across a device when the device is in portrait orientation. Like this:
And let's say our device is the Nexus 5. As you can see in the above example, there are 7 identical images side by side, from the left to the right side of the screen. With the following example, you should probably be able to figure out "how large [you] should expect [images] to be" for various circumstances:
We know the Nexus 5 is an xxhdpi device because we looked it up in Google’s Device Metrics:
Let’s start doing the math by accounting for padding. I assume you have padding by default - check it out in your values/dimens.xml to make sure:
That’s 32dp we need to account for.
3. Next, we know the width of the Nexus 5 is 360dp or 1080px, so let’s figure out the width of one of our seven images:
Let’s make the decision that we’re going to import our image with Input Density of xxdpi in mind.
360dp (full) - 32dp (padding) = 328dp (remaining for 7 images)
328dp / 7 = 46.9dp (approx)
Let’s go to androidpixels, highly recommended site for conversions, and look up what that means in pixels - in this case, it equals 140.7px.
Create a png version of our image that’s 140.7px and import it as xxhdpi (we'll import it in the same dp signature as the device).
Since Adobe Illustrator and Adobe Photoshop won’t allow decimal sizes, you can go with 140, and make up the difference with spacing in Android Studio. The math suggests that if there are 6 gaps between these 7 images, and we lost 0.7px per image, that’s 6 * 0.7px = 4.2px which we may have to account for somewhere.
After you import the images in Final Android Resizer, highly recommended for resizing images - or just import it into the proper drawable folder - there’s one final step: update the content_main.xml with the correct image, and make sure to do it for all seven ImageView elements:
This is what it should finally look like:
Do these steps again with the size of the device in question.
This is also not the only way to do this. You can use layout directories to pinpoint specific device dimensions and affect views within them. See another post I made about this:
Differences between scaling images with dpi as opposed to dp

Related

How to create two separate layouts for 10'' and 9.7'' tablets?

I'm developing an application for Android tablets. I've read this Google's guide several times, but something justs doesn't seem right:
I've been testing the app on a Genymotion's Google Nexus 10 (10.1''). Yesterday I bought a 9.7'' tablet to test on a real device, but the interface was as if I set the Android Studio layout preview to Nexus 9 (8.9'').
So I guessed this:
More than 10'' is treated as xlarge.
Less than 10'' is treated as large.
So I moved all my layouts to /layout-xlarge-land/
And began designing a new one to fit my 9.7'' tablet, and put into /layout-large-land/, basing in the 8.9'' Nexus 9 (that looked exactly as in my 9.7'')
But then my surprise was that Android Studio (or actually just Android) treats both 8.9'' (=9.7'') and 10'' as large.
I have tried several answers saying to rename the folder to /layout-sw768dp/, but they don't work.
So I need two folders: one for 10'' tablets and another for 9.7'' (yes, they are not equally treated).
How should I name them?
I need two folders: one for 10'' tablets and another for 9.7''
Those are not meaningful figures, and therefore there is no means of having different resources for them. They are not meaningful, because they do not take aspect ratio into account. Not all Android devices have the same aspect ratio: some are 16:9, some are 16:10, some are 4:3, some are 1:1, some are other things entirely. 10", 9.7", and kin are primarily for marketing purposes.
This is no different than in Web design, where designers don't speak in terms of the diagonal dimension of a browser window all that much.
For technical purposes, while you can use the legacy -large/-xlarge sorts of qualifiers, they were supplanted about four years ago by the -w/-h/-sw qualifiers:
-w640dp indicates resources that should only be used on devices whose current width is 640dp (i.e., 4 inches) or larger, where you can supply the number you want where I have 640
-h640dp indicates resources that should only be used on devices whose current height is 640dp or larger (again, with customizable values)
-sw640dp indicates resources that should only be used on devices whose smallest width, in any orientation, is 640dp or larger (in landscape, the "smallest width" is actually the current height)
This gives you control much like how Web designers use media queries in CSS stylesheets to change CSS rules based on particular heights and widths.
Now, since nobody knows what you think is a 9.7" UI and what you think is a 10" UI, nobody can really help you either consolidate that into one set of layout rules or provide you with qualifier values that will work. You are going to need to determine for yourself where your dividing line is, based on current width, current height, or smallest width. Let's pretend for the moment that you choose 800dp current width as being your dividing line. Your smaller-than-800dp layouts would go in directories like res/layout/ and res/layout-land/. Your 800dp-or-larger layouts would go in res/layout-w800dp/.
I have tried several answers saying to rename the folder to /layout-sw768dp/, but they don't work.
You may wish to consider editing your question and explaining what "they don't work" means.

Why aren't standard physical length units like mm used for touch UI layout?

If you're laying out an interactive touch UI element, such as a button, you want something with a sensible physical size, so the user can hit it comfortably. In this way, laying out a touch UI is just like laying out physical buttons and knobs on an electronic device. And for this kind of physical engineering, millimeters (or inches) are the unit of choice.
For some reason this doesn't seem to be the case in touch UI design. I don't consider myself extremely well-read in the subject, but I've honestly never seen anybody use mm as a unit in, say, an Android layout file. But I've seen endless debates about "px" vs "dp" vs "sp" vs who knows what.
The "device-independent pixel" (which on Android is defined in terms of physical length - 1dp ≈ 0.16mm) seems like a really convoluted way to specify a length.
Why not just use millimeters?
Is it a problem with devices not supporting these units properly? Is it a cultural thing (programmers might be more used to thinking in "some sorta pixels" rather than physical units)? What's going on?
Generally, you'll find mobile usability folks talking about millimeters. But programmers and visual designers talk about density-independent pixels or points (1 Android "DIP" = 1 iOS "point") because even if you could specify a measurement in millimeters exactly, you'd end up with rounding issues or half-pixel anti-aliasing ugliness:
1mm equals 6.3 DIP (degree of precision there depends on the exact DPI value of the screen, since dip are quantized to the nearest of 120/160/240/320/480/640 dpi). That means on a standard G1-style 160DIP screen, if you specify a button as (let's say) 8mm, it'd be 50.4 pixels on that screen - good luck rendering that with any degree of precision, or telling Photoshop to end a line exactly 50.4px. And just rounding isn't much of a solution; the screen is still a fixed total width in pixels, and those rounding errors would compound in ways that mess up symmetry if you're (let's say) laying out a grid of buttons with specific sizes and padding amounts.
Specifying that as (let's say) 48DIP is much better, since that smoothly scales: 48px at 160DPI, 72px at HDPI (240) and 96px at 320DPI (AKA 2x in iOS terminology), no fractional pixel rendering or rounding needed.
As to why exactly the 160DPI pixel won out as the 1x mobile unit of measurement for the density-independent pixel, blame the first few iPhones and the HTC G1, which shared that configuration.
I think the W3C provides a decent explanation of various units of measurement for screens, and where each has advantages and disadvantages. I would also very highly recommend Roman Nurik's Density Independent Pixels video. While it doesn't directly answer your question, it provides a lot of great information.
Here are my arguments for DPs instead of mm:
Resources
This is probably the biggest one. When designers and developers create image or video assets, we don't use physical sizes. If you take a picture with your camera, you can't say that the picture is 5 inches tall. How tall the picture is depends on how you decide to print it out.
Thus if I want to display an image to my users or I want to create a button graphic, I can't simply create the resource at 10mm wide by 10mm tall. That one image will render at different sizes on different screens. Even if the device/code does scale the image to exactly 10mm tall, it will look incredibly pixelated on most TVs, and/or will have more detail than a low density device (such as a watch) will be able to display (thus wasting the device's resources).
The answer then is to export a single image at different sizes so that it looks good across multiple devices.
Of course there are other ways around this. Vector graphics could solve this problem, but that's a completely different topic.
DP
As for an Android-specific answer- we kind of do. As you pointed out, we use DP which can be roughly converted to conventional physical units of length such as mm.
However, using DPs works in tandem with Android's density buckets to allow designers to create assets for a finite set of display sizes. In my opinion, labeling these buckets with a physical measurement would be a bit more confusing, as a 4.2" phone might be in a 4" bucket.
SP
SPs are used primarily for text to allow the user to customize their font size. Defining a font size in pixels or mm would be misleading once the user changes their scaling.
it is because Android supports many device sizes and resolutions. Would you want to develop an app that accepts touches in certain places measured by mm and have that location be different on a phone vs a tablet? Or a hi-density tablet of the same size as a low density tablet? Or even just the height/width ratio differences between phones and tablets.
Millimeters is a hard measurement that reflects real life distance, but not the number of pixels. Units such as "dp" and "sp" take into account the pixels as well as the size
Using sp/dp
will make your
Android applications
compatible with
multiple screen
densities and
resolutions
Which is not possible with mm
where your app layout is independent of resolution .

Resolution for android app design

I start to design small app for android. But this is my first android app design. And I have a question about devices and displays.
I have read all developer guidelines at http://developer.android.com/, all about DPI and pixels. And still not clear with question.
I want to design in Photoshop CS6 because is the best way for me.
In guidelines i read "One approach is to work in the base standard (normal size and MDPI) and scale it up or down for the other buckets. Another approach is to start with the device with the largest screen size, and then scale down and figure out the UI compromises you'll need to make on smaller screens."
I want to start with the largest screen size so this is XHDPI 320DPI. As an example I want to choose Nexus 4. What resolution (pixels and DPI) do I need to choose for PSD?
I think I need to create PSD with 1280x768px and 320dpi. Is that right? If so, when I need to scale down to 160dpi I have to create new PSD with 160dpi and resize the elements from 320dpi?
Please help me someone I'm confused.
Density and screen size are not the same thing.
XHDPI is the density. 1280x768 is the screen resolution, NOT the screen size. The Nexus 4 has a 4" screen, which is considered "normal" size. If you had a device with an 8" screen and resolution 1280x768, it would be 160dpi, and would be MDPI. However, you can still use the 1280x768 asset you created for the Nexus 4 and the system wouldn't have to scale the image.
Here's how all this relates:
With the Nexus 4's "normal" sized screen, you can display all sorts of UI elements, keeping in mind that they need to be large enough to read, tap, etc. If you launched the same app on an 7" screen, which is considered "large" you might add additional UI elements, since you have so much more real estate. Ok so far?
Now, let's say the 4" screen and the 7" screen have the same resolution (1280x768), they will have a different density. The 4" is XHDPI and the 7" is HDPI (my Nexus 7 reports 213dpi).
If you had a 80x80 image, it would be 1/4" square on the Nexus 4, but 1/3" square on the Nexus 7. The whole UI would look larger and somewhat Fisher-Pricey. Thankfully, Android scales the UI for you, as long as you use "dp" to declare the size of UI elements. You can provide assets in different densities so Android won't have to scale bitmaps too much -- though it still will.
So, if you're developing a phone app, target the normal screen first (and XHDPI if that's your dev device), and provide all the assets in XHDPI. Then create alternate layouts for large screens if you want to make the UI more usable for tablets. Lastly scale your images for other supported resolutions.
You can use PSD, but personally, I prefer vector-graphics as they scale beautifully.
I'm not a PhotoShop user, but since it's raster based, I would start with a higher resolution than you expect using, and scale down. At the very least, I would design for a 1600x2560 Nexus 10, and then scale down from there. In my process, I use CorelDraw (long story), design icons in 1"x1" boxes and then export in the various resolutions.
a little more detail on what you are trying to do would be helpful. Are you trying to design your icons, or the entire UI, or what?
In android, the UI is designed mainly through xml, and the default styles should be used when possible to stay consistent with the rest of the OS and looking nice. For many apps, there is no real graphical work to be done accept maybe launcher icons, which there are guides on the developer site for.
If you are trying to design some of your elements like icons, figure out how big they would need to be on the largest screen size, and start from there. then you can scale them down, but you should not actually be drawing the whole UI or anything. Take a look at how the graphics are done in some of the android examples, I find them to be extremely useful when trying to figure out how to do things.

Creating base PSD to design Android App UI for mdpi, 320/480px device

I'm starting my first Android Phone design work. I have some experience with iPhone, iPad design but Android is totally different, I'm even not sure how I should create my base template.
Here is the device info I'm going to design. the app that will work only on this device, no need to multiple screen compatibility thing.
mdpi
256K color
3.5"
~165ppi pixel density
320px/480px
So, do I create my photoshop file for 320px/480px, 72px resolution, rgb?
Appreciate helps!!!
Google has made a whole site dedicated for your needs:
http://developer.android.com/design/index.html
In your case, your PSD settings should be setup like this:
NOTE/EDIT: Notice DPI is set at the default of 72. This is because DPI is meta data for printers. When you read DPI in phone specs, they are talking about the physical representation of how far apart the LCD is packed together. Resolution of the image (320x640) is the only thing you need to care about.
Have you looked at the Android Design site? It's specifically designed for... well designers.
Look at the devices display section and also the supporting multiple screens page to get an idea of what the general categories of screen sizes are and what an acceptable size and range for these is.
Android in general uses DIP's (Display independant pixel) so the actual pixels per inch depend on the screen you are creating art work for. You have to design for xlarge, large, medium and small screens with differed densities. General advice is to start with medium density screens and then you can increase density and decrease it in your artwork as needed. The link above gives the general dp dimensions of each screen size and density ranges of different types of screens. There should also be some info about converting dp to pixels.
While google frowns on what you are asking (designing for 1 device in particular), you said the device as 166ppi so you could just use 165 pixel / inch in your setting and set the height and width of the PSD depending on the size of your screen (whatever it's width and height is in inches).
This Smashing Magazine article on designing for android should really help. It's old but relevant.
Android is very different. If you learn how to do use the properties offered by android the right way it works greats.
Quote from developer.android.com
Each screen size offers different possibilities and challenges for user interaction, so in order to truly satisfy and impress your users, your application must go beyond merely supporting multiple screens: it must optimize the user experience for each screen configuration.
There are some tools you should get to know as well such as 'draw9patch'
The best thing to go off of is to simply create a layout in Photoshop just to get the layout down. It will not really matter what exact size as long as you have a rectangular shape. Make your layout and then start to make it fit in android.
Many great tutorials online, but as I mentioned before. Create your layout, then start to customize it for android by using tools such as draw9patch
Because you said your screen was ~165ppi, ppi = pixel per inch. Also, the Android docs describe 160dp as the generally accepted size for MDPI. – Ali Feb 7 at 22:22
so why in google samples
( ex : IDEName\AndroidSDK\samples\android-8\NotePad\res\drawable-hdpi ) ,
if open image ( ex : app_notes.png ) in photoshop and press ctrl + alt + i , to see resolution , its 72dpi !
but Ali says MDPI = 160dpi , HDPI = 240 , ...
so its must be 240dpi , not 72dpi.
The bitmap requirement is similar to preparing graphics for print vs. the Web. If you have any experience with print production, you’ll know that a 72 PPI image will look very pixelated and blurry when scaled up and printed. Instead, you would need to redo the image as a vector image or use a high-resolution photo and then set the file’s resolution at around 300 PPI in order to print it without any loss of image quality. Screen density for Android works similar, except that we’re not changing the file’s resolution, only the image’s size (i.e. standard 72 PPI is fine).
Android Smartphones And Display Sizes

android developers - what do you need from the designer?

i am NOT an android developer and im trying to understand what they need in terms of graphical resources to make an app that functions across many android devices.
i have (tried to) read this page http://developer.android.com/guide/practices/screens_support.html , but find it somewhat bewildering. they talk as if screen density is the important thing "Supply alternative bitmap drawables for different screen densities" but then, if you dont know the size of the screen, you cant really think in terms of layout. is the idea to make buttons and logos that are the same size on all screens with the same density, such that on a large screen there is just a bunch of space, and on the small screen its all packed in tight? i dont understand how just thinking in pixel density gets me any closer to knowing what to provide.
are you supposed to create resources for every screen size AND pixel density? say it aint so.
anyway can somebody tell me... if you were developing an app what do you need for graphics? is it possible to provide graphics that are large and just let them scale down? is it inevitable that the devloper will have to mess with the graphics himself anyway? or can he be provided with sets of png files of certain sizes that will be ready to use?
thanks!
Here's what we do at my work place. Suppose we get a desing for the app. We make our designer create 3 psds versions for the same desing. the 3 psd's are for the 3 ranges of desnity. The size used for the psd are
240*320 (Low Density)
320*480 (Medium Density)
480*800 (High Density)
Most of the time when I write layouts, I use wrap_content which means a view must take the size of the content it wraps. Which works most of the time as I have a density specific version of the design so the image i use as background should be suitable. The thing to note is that, in android you can can put the 3 sizes of the same image in different folders such as drawable/ldpi, drawable/hdpi.
Eg: you have a bg.png and have a version for large phones and a version for small phones. You put the big bg.png into hdpi folder and the small png in the ldpi folder. Android will automatically select the appropriate image based on the phone density. But you need to make sure the file name is the same.
There are cases where you need to resize you background images without makeing the image looking too scaled. For this android uses the draw9patch tool. With this tool you can specify areas which can scale and areas that shouldn't scale.
9 Patch png's are your friend. Read up on them here:
http://developer.android.com/guide/topics/resources/drawable-resource.html#NinePatch
and here:
http://developer.android.com/guide/developing/tools/draw9patch.html
Those are your best bet for any kind of graphic that will stretch nicely (i.e. not gradients, they will come out slightly pixelated on some screens probably) The power of these types of images is that you can tell the system which pixels to repeat if it needs to stretch the graphic. This means that stretching can be done without loss of image quality (again depending on your image and how you choose to make the nine patch. The "show bad patches" button in the draw9patch program will show you potential problems. Hint: keep your repeatable pixels down to 1 on left and 1 on top and you'll have no problems with bad patches) Any graphics that can be made in to 9 patches will only need 1 size since the system can effectively make it whatever size it needs.
are you supposed to create resources for every screen size AND pixel density?
You may if you like. This would ensure that the application will look great across all devices. I understand that this is not feasible for all projects though. In general if you make separate resources for the different densities you'll get something that looks acceptable on most of the devices out there. All of the devices are classified as ldpi, mdpi, or hdpi (there may be an "extra high" level now too, I am not certain off the top of my head) So if you supply graphics for those 3 densities then the system will know where the device falls under and will pull the correct graphics.
is it possible to provide graphics that are large and just let them scale down?
Yes the system will scale down your graphics if needbe. But be aware there are consequences with this approach. First every time the system hast to scale a graphic up or down it is going to taking up CPU and memory to do so. This may not be an issue if you have relatively few things to scale, but if you have many it could cause noticeable lag time during on the lower power phones. Second, To my knowledge all of the graphics in android are raster, which means if you are letting the system scale something up or down image quality is going to decrease some. Again depending on the specific images this may be more or less noticeable on the actually device at runtime.
My best advice is supply them with resources of a few different sizes and run the app on as many different devices as you can. Once you see how your different resources look on the devices of different sizes you'll have a much better feel for which ones you need to supply to get the UI looking as consistent as possible across the largest swath of screen sizes and densities.

Categories

Resources