I am making an app in Android Studio and I have just started making the splash screen. However, I have been having trouble making the image show up as the right size/quality in the android:background property.
Here is the XML code that I am using to display the drawable:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="#drawable/main_logo"
android:keepScreenOn="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:context=".Splash">
</RelativeLayout>
The drawable is displayed, but it is a small image in the top left corner of the screen.
The original image is 2500 x 2500 pixels at 9999.99 pixels/inch resolution, so it would have no trouble resizing.
How would I specify to use a different size like xxhdpi instead of hdpi which has been resized, or use the original image and resize it in the center of the screen?
You have to actually provide separate resources for each folder - mdpi, hdpi, xhdpi ... The system chooses the best to use based on the specific device. If only a single resource is provided for all situations, it will be used by default and you, or your client, will likely not like the results.
See Supporting Multiple Screen Sizes for more information.
Related
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
So, I have googled a lot, but still cant quiet grasp the concept. I have 3 folders : xhdpi, lhdpi and mhdpi. I do understand the conversion and downscaling to different dip and screen densities. Android selects resources for the right screen type when the application runs.
But, how do I start? I made a background for my application in Photoshop. The background was defined in 720x1080px and exported as an .png file. I put the .png in the xhdpi folder. Everything worked out fine on my Sony Xperia Z, but when a friend loaded it on his Galaxy 3 the background was "to-small" and did not fit his screen. I assume this is because the bacground was to small.
But how large do I need to make it? What px-sizes should xhdpi drawable resources be to fit every single xhdpi screen?
Would a good approach be to start with the largest size, xhdpi? And then convert the drawables down to mdpi and ldpi later on? If so, I need a starter size in px so I can create the background for the application in Photoshop.
Here is how I use the background : (Note, i changed my height to fill_parent it fixed the "not filling the whole screen problem")
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="#drawable/bg_xhdpi" >
</RelativeLayout>
To make PX sizes scale appropriately you will need to scale using the following ratios:
2X for XDPI
1.5X for HDPI
1X for MDPI (baseline
.75X for LDPI
When you are specifying sizes in your code (or XML), use the DP parameter to specify the value (or SP if you are specifying fonts).
for example: android:layout_marginLeft="12dp"
Here is the docs: http://developer.android.com/guide/practices/screens_support.html, you will notice this image, and a lot of other details describing this.
You can find in this table a briefing of different devices screen densities and resolutions; according to it, Galaxy SIII is xhdpi with a resolution of 1280 X 720. Besides, you could want considerate to follow compatibility mode guide to avoid rendering issues in multiple screens.
I have an app that displays a bitmap in a TextView as a "drawableTop":
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="fill_parent"
android:layout_weight="1"
android:drawableTop="#drawable/bitmap"
android:gravity="center"
android:text="#string/text" />
The bitmap comes from a PNG file in the res/drawable folder, let's call it bitmap.png.
I need to support multiple screen sizes and densities, and want to find the cheapest way (in term of how many PNG files I need to have in res/* folders) to do it.
Various densities: Phones only
I've come to the conclusion that it's enough to have the bitmap.png in res/drawable-xhdpi folder. When being displayed on phones with high density, it will be displayed as is, while on phones will lower density, it will be scaled down automatically.
In other words, no need for having lower resolution versions of the bitmap.png in res/drawable-hdpi, res/drawable-mdpi etc.
Basically only one version of the PNG file is enough for all phones.
Various densities: Tablets as well
Now, the problem arises if I want to support as well tablets: large and xlarge screens.
On tablets, I want the aspect ratio of the icon to be the same as it was on phones: If the bitmap took 1/4 of the screen on phones, I want it to take 1/4 of the screen on tablets. I cannot reuse the same PNG file as before or it would look too small since the tablet just has more pixels... So for tablets I need a higher res PNG. And this applies both to large screen and xlarge screens.
Which results in the need for 3 folders, and 3 versions of the PNG:
1: res/drawable-xhdpi/bitmap.png
2: res/drawable-large-xhdpi/bitmap.png
3: res/drawable-xlarge-xhdpi/bitmap.png
But 1 and 2 are basically lower res versions of 3.
So is there an easy way to have a single folder not 3?
If you want to keep only one image for all resolutions, why not keep in res/drawable and res/drawable-land folders?
If you are talking about cheapest way to do this (not adding more than one image in drawables), then use 9-Patch Images. If you dont know about it, then have a look n learn usage here:
http://www.androiddom.com/2011/05/android-9-patch-image-tutorial.html
http://www.androiddom.com/2011/05/creating-custom-drawn-button.html
Judging from your question, you don't need different orientated images for tablet or phone.
If you want the image to take 1/4 size on both devices, then define your image in your xml as using d(i)p. This will scale the image to the same size on all devices.
d(i)p is scaled relative to 640x480 (or 480x640 resolution for portrait orientation).
So you can calculate different combinations of resolutions to cover 1/4 screen space, such as 320x240 or 240x320
If you want control over the scaling of your image, I would suggest putting the image in an ImageView. This will allow you to use the android:scaleType property to scale your image how you wish.
You can set the background of your TextView to be transparent, and have the ImageView below it contained within a relativeLayout of your desired size to achieve the same effect as you current have, like so:
<RelativeLayout
android:layout_width="320dp"
android:layout_height="240dp"
>
<!-- Images at the top of the xml are drawn on the bottom! -->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:src="#drawable/bitmap"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="#string/text"
/>
</RelativeLayout>
Also consider using alias resources.
This will allow you to define an xml file which will act as if it's the real PNG image (and is referenced as such in R.drawable. , but is actually a reference to another image.
From the linked Google documentation:
To create an alias to an existing drawable, use the element.
For example:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/icon_ca" />
If you save this file as icon.xml (in an alternative resource
directory, such as res/drawable-en-rCA/), it is compiled into a
resource that you can reference as R.drawable.icon, but is actually an
alias for the R.drawable.icon_ca resource (which is saved in
res/drawable/).
I have an activity that contains a LayoutView with a png as background to give a nice frame effect as the rest of the app, ad a listView loaded in this LayoutView .
I have tested the app with all screen sizes and resolutions profiles in the latest version of ADT and works fine with all screen, but with these configuration
-Tablet 10.1" WXVGA mdpi
-Tablet WSVGA 7" mdpi
-Nexus 7 7.17" 800x1280 tvdpi
the list exceed the frame of background PNG and looks horrible.
Others configurations (also with the same resolution but different density and vice versa) works.
To fix the issue I must increase the listView margins, but this cause issues with all the others configurations.
How could I solve this problem, without change the graphic design of the app?
edit
I have added a sample of the problem, the listView must remain in the black area but in the described situations exceed the area
The red area is a LinearLayout1 with inside another LinearLayout2 with a ListView, the margins are large because the vivid red area contains the frame of the png used as background of LinearLayout1
I would say you would need to resize/modify your background image that match certain screen density. In android you have a choice between with these folders to store images.
drawable, drawable-hdpi, drawable-hdpi-v11, drawable-ldpi ,drawable-mdpi, etc.
http://developer.android.com/guide/topics/resources/providing-resources.html
The Android O.S will try to to use the most appropriate image based on the hardware screen resolution. So see if making the image bigger/smaller helps with the listview for certain screen density.
Screenshots would definitely help if this is not the case :P
It seems that you use same background for all screens and dpi.
In this case, it is hard to do it (I found the same problem).
There are some solutions:
Use ninepatch for the background.
Divide background into several areas, and don't use margin instead of view with static size, as below:
<layout>
<view id="left" size="20dp" background="left.png" />
<imageview id="content" size="0dp" weight="1" background="center.9.png" />
<view id="right" size="20dp" background="right.png" />
</layout>
By using this, the layout does not relate with screen and dpi.
According to the docs, using the CENTER attribute will not perform any scaling on the image. Yet, when loading a PNG via XML like shown below, it appears significantly larger than it should be.
What's going on?
I figure the image is being scaled when it's loaded, but why? Is there some manifest tag missing, or should I be using a different folder?
<ImageView
android:src="#drawable/auth_logo"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scaleType="center"></ImageView>
Any help would be appreciated.
Scaling of image is caused by difference between your image's DPI and screen DPI.
Android manages scaling so that DPI matches.
Image's DPI is determined by res source folder where image is stored (drawable / drawable-hdpi / etc), and actual screen density, which is given physically and is fixed for given device.
To avoid scaling, put your image into res/drawable-nodpi folder.