I've read pages over pages, but i still have problems with layout for multiple screens.
I have an image 1080 * 300 pixels that occupy nexus 5 screen horizontally, and is aligned on top of layout (a sort of header). Now if i scale it for xhdpi screens (like galaxy nexus and nexus 4), i don't obtain the same result. by follow scale unit, my 1080 px width image in xxhdpi becomes 720 px image. This dimension fit perfectly for galaxy nexus screen (it's gnexus screen width), but not for nexus 4 that is bigger (768 px), so image don't fill all screen width and i have a blank space on his right.
If i try to scale image to 768 px width, it fit for nexus 4 but not for gnex.
I've noticed also when i change virtual device for preview, this error from adt console:
Displaying it with ', , Locale Language ___Region __, Left To Right, sw384dp, w384dp, h640dp, Normal Screen, Short screen aspect ratio, Portrait Orientation, Normal, Day time, X-High Density, Finger-based touchscreen, Soft keyboard, No keyboard, Hidden navigation, No navigation, Screen resolution 1280x768, API Level 19'
What's wrong?
You can use a custom view called ScaleImageView which is written by Maurycy Wojtowicz.
Class is defined like below:
This view will auto determine the width or height by determining if
the height or width is set(exact size or match_parent) and scale the
other dimension depending on the images dimension This view also
contains an ImageChangeListener which calls changed(boolean isEmpty)
once a change has been made to the ImageView
Here is how you are going to implement it.
Create a class named ScaleImageView.java and copy contents of the link above.
In your xml file, create a ScaleImageView, just same like ImageView (the example I am writing below is for filling screenwidth, and scaling height according to that so there will be no empty spaces on right/left)
<com.project.customview.ScaleImageView
android:id="#+id/scaleImageView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="#drawable/file" />
If you need to declare and set programmatically in your Activity, it is also the same as using ImageView:
imageView = (ScaleImageView)findViewById(R.id.scaleImageView);
imageView.setImageResource(R.drawable.file);
Related
In researching android image sizes for different sized screens/densities etc., I've found an absolute tonne of things, a lot of which may be deprecated, and a lot of which may not be relevant to my situation, so I thought I'd ask for general advice.
My basic question is how big should I make my background image in pixels, or inches or centimetres? Probably pixels would be best.
My app is in locked in landscape mode, I don't need to worry about orientation.
I'm using a vector image, so I don't need to worry about scaling and quality issues
So, I want my background image to fit onto a ten inch tablet, so that it fills the whole screen with no scrolling.
On phones, I want the height(which would be the width in portrait mode) to match the height of the screen, and my image will be in a horizontal scroll view, so scrolls left and right in landscape mode.
So, do I need to do the whole creating different image resources for different dpi's thing, or will one do? What size should I make it?
I will also be lining up textviews with specific parts of the image, so presumably I'll need different layouts, as the lining up of textviews relative to the image will probably vary from screen size to screen size, resolution to resolution,bigger textviews for bigger screens etc. How do I implement this?
Thanks
Vector images should be used for icons only. In your case i'd just use a drawable & make sure you have different images for the different densities. Then create different layouts for phone and tablet. You should use a scrollview on the layout for the phone
The google pixel is a good representation of an android phone: It has a 1080 x 1920 resolution at 441 dpi. Then from the the android developer docs:
xxhdpi ~ 480dpi
you can scale the 1080 x 1920 down by the (3:4:6:8:12) ratios. if you image
has a different aspect ratio make sure that that the width or the height matches with 1080 x 1920 depending on the orientation of the device
I am just using simple default layout and not adding any of these layout versions; l-dpi-Layout,m-dpi-layout etc.. then what exactly the resolution of my default layout is?
Let say i add an image and define its width-height as 20dp X 20dp. This image is looking perfect in layout Preview screen, but would it look same in 1440X2560 screen or 1920X1080 screen.
My concerns are:
what exactly is the resolution of default layout is?
How would android know that the 20 dpi i am defining fits best for 1080X1920 resolution and 27dpi fits best 1440X2560 screen, when i am writing 20dpi in my default layout which perfectly fits in layout preview screen
The system assumes a target device with a density of 160dpi. When you define the size of yout image with dp unit, Android adapts the size according with the resolution of the device. For example, if you put an image of 100dp x 100dp in a 160dpi device it will take 100 x100 pixels, but in a device with a 640dpi screen it will take 400 x 400 pixel
By default when you create a template app, your main content layout has two parameters values as layout_width=match_parent and layout_height=match_parent. match_parent value means whatever the screen dpi size the mobile has, it stretches all the way to its size of width and height respectively which is calculated by android automatically when it runs its layout pass to position views (including padding). So in this context the default resolution of your layout is what your mobile has minus the size of statusBar and navigationBar.
Android translates the DPI value you enter for your width and height into number of pixels internally to size your views. You can also put the size of your view into number of pixels but its not recommended.
my problem is quite simple, i never did this before but now i'm forced to search for a solution.
working with layout-normal
Let's say i have a image background set to match_parent, with 3 different points on it, on that points i should place buttons, i added the buttons and set some margin dp's till i meet the points. for example: layout_marginTop="50dp"
on the preview screen it looks ok, but when i start some emulators from the same size category "layout-normal"
3.7inch; 4.0inch; 4.65inch ... it looks different. it looks ok only on the device size i got the preview
What should i do? what can i do?
i tryed to fix the image, created a linear layout, set the image as background, set the size of the screen (let's say 400x250) and added the buttons in the layout.
but now when i run it in different emulators i get empty space and the image does not fit the entire screen.
Hrrrrrrr! what can i do?
Get your ImageView Size with a onPreDrawListener, or if it fill the Screen you can get it with getDisplaySize
You know the points in your image where to place your Buttons:
orginal image 480x800 -> button1 left:XX px top:xx px
new size 720x1280 -> button1 left: YY px top: YY px
with this info you can calculate where to place the Button on real device with an other Resolution than 480x800 (using the rule of three)
then set your margins programaticly
actualy i found out that android documentation gives you other posibilities in layouts arranging.
-- layout-normal; layout-small; layout-large; layout-xlarge
-- layout-sw300dp; layout-sw360dp; layout-sw450dp; layout-sw600dp;
layout-sw800dp; where sw means smallest available width required by your layout resources
-- layout-w300dp; layout-w360dp; layout-w450dp; layout-w600dp; layout-w800dp; where w means the minimum width required for the layout
-- layout-h200dp; layout-h260dp; ... where h means the minimum height required for the layout
i used to give them the smallest available width.
I am a bit confused about resolution of Android Tablets. Each Tablet has different resolution and size. How can I design images, logos, buttons, etc to fit all android Tablet size in Landscape mode.
You need to make the images for only one size (or for one device).
Lets say you are working on a tablet with screen size 640x960.
You can then make a layer of size 640x960 and add the images to that layer.
Once you have your layer with all the images you want on it, you must then scale that layer up or down depending on the device screen.
So if you made an image for a device with screen pixels: 640 x 960, and you test it on a different device with screen size 400 x 800, you would then scale the layer that contains your images like so:
layer->setScaleX(640/400);
layer->setScaleY(960/800);
And the layer will stretch inwards to fit the smaller screen.
My question is just in the title.
I try to put an image to my layout, i tried this with a FrameLayout's background with wrap_content width and height and also tried with imageView with all of the possible fitScale properties.
I just cant see why my 720 px width image is HALF on the width of my phone's screen which is a samsung galaxy s3 with 720 px width....
My real question:
What is the best way to ensure that my pics in applicaion wont get any distortion?
First of all, you need to think in screen densities and dip values, not pixels. That means that you are dealing with a "virtual screen" where 1 dip (density independent pixel) represents a different amount of real screen pixels depending on the device.
For drawables you have the following categories for getting crisp results on any screen:
ldpi (Scale factor 0.75)
mdpi (Default / baseline: scale factor 1.0)
hdpi (1.5)
xhdpi (2.0)
Create different sized versions of your bitmaps based on these scale factors to get crisp results on any screen. You should start from xhdpi as highest resolution to avoid quality loss because of upscaling.
Put these different versions into their respective drawable folders (res/drawable-ldpi, res/drawable-mdpi...). These different versions of one and the same bitmap must bear the same file name of course, otherwise that won't work.
Second of all you shouldn't make strong assumptions about the device screen height and width. You need to layout your views and graphics so they dynamically make use of the whole screen not knowing the exact screen resolution. However, you can make weak assumptions about these screen resolutions based on the configuration qualifiers
small
normal
large
xlarge
Try to avoid fixed sizes for your views based on any assumptions. Always avoid "px" values in layout XML files. Use "dip" instead.
Read the documentation Supporting Multiple Screens for more information.
What you want to achieve sounds as if you want your image to take up the full width of the screen.
If you set the image as a background of any view (FrameLayout for example) then the displayed clip of the image depends on the size of that view.
If that view has layout_width / layout_height set to wrap_content then the size of it depends on the dimensions and arrangement of its child view(s).
In case of FrameLayout it depends on the size of that single child of FrameLayout.
If you're using ImageView the image will be scaled to fit into the size of the ImageView by default. The size of the ImageView depends on its layout_width / layout_height values. If you set these values to match_parent and if the ImageView has enough room "to grow" you should be able to see your image stretch all over the screen.
The "room to grow" depends on the ImageView's context in the layout. Does it have neighbors that take up room? Is the parent view too small (because of wrap_content for example)? Look for these possible problems.