How does object scaling through different screens work? - android

I am new to Android, but I still managed to design an app that runs just fine on my smartphone. I read the tutorial about Android support for different screen sizes and I thought: "Ok, that's great, Android itself will scale the app in order to fit other screen sizes. I just need to have different images for different resolutions so that they will look better."
Well, it seems I didn't understand how it works exactly. By using a Virtual Device within Android SDK, I run my app on a smaller screen size. Unfortunately, there was no automatic "scaling" and half of my app layout is not shown on the screen. An imageButton that on my smartphone was one sixth of the screen, it occupies maybe one third of this new smaller screen.
What did I forget? I read some explanations and other posts but the info I got seemed to indicate an automatic scaling that doesn't happen... Maybe I miss some basic rule?
Thank you
EDIT:
Here below I add a bit of my code as an example. How should I change it in order to make the ImageButtons fill the smartphone screen in the same way, even if the screen sizes change? (if it's possible).
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/greenbackground"
tools:context=".GameFrame" >
<ImageButton
android:id="#+id/image1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="30dp"
android:layout_marginTop="27dp"
android:background="#android:color/transparent"
android:clickable="false"
android:contentDescription="#string/app_name"
android:src="#drawable/empty" />
<ImageButton
android:id="#+id/image2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/image1"
android:layout_alignTop="#+id/image1"
android:layout_marginLeft="16dp"
android:background="#android:color/transparent"
android:clickable="false"
android:contentDescription="#string/app_name"
android:src="#drawable/empty" />
<ImageButton
android:id="#+id/image3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:layout_toRightOf="#+id/image2"
android:layout_alignTop="#+id/image2"
android:background="#android:color/transparent"
android:clickable="false"
android:contentDescription="#string/app_name"
android:src="#drawable/empty" />
</RelativeLayout>

You need to use a ScollView in order to display UI elements which aren't visible on the small screens. Keep in mind that a ScrollView can only have one child:
<ScollView
[...] >
<MyParentLayout
[...] >
<MyUiElements
[...] >
</MyParentLayout>
</ScollView>

Related

Android relative layout using dp jumps all over

I've tried to match as exactly as possible the tablet this is being designed for, a Samsung Tab S2 - 9.7" screen size, 2048x1536 - I've created an AVD to match that.
I've lined up the images as shown here:
But when I deploy it, they jump around, as shown here:
They get even worse depending on other tablets, but I'm just trying one for now. I'm using a full screen relative layout with DP for the dimensions and margins, so why do they jump around so much? Shouldn't it always be the same distance from the top/sides? How come even though the dimensions and pixels match exactly in the AVD and the tablet, it moves around?
I'm completely lost, I've read everything I can from setting margins in code to absolute layouts (no longer supported). Everything points back to DP, but even using an exact match tablet and designer, they change location and size.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_buttons"
tools:context="com.cimulus.samocoseat.MainMenu">
<!-- This FrameLayout insets its children based on system windows using
android:fitsSystemWindows. -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fullscreen_content_controls_a"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="UselessParent">
<ImageView
android:id="#+id/seatView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/seat"
android:layout_marginTop="60dp"
android:layout_marginBottom="60dp"
android:layout_marginLeft="245dp"
/>
<ImageButton
android:layout_width="124dp"
android:layout_height="75dp"
android:text="Seat Back Forward"
android:id="#+id/seatBackForward"
android:background="#drawable/left_inactive"
android:layout_marginTop="266dp"
android:layout_marginStart="38dp" />
<Button
android:layout_width="124dp"
android:layout_height="75dp"
android:text="Seat Back Forward"
android:id="#+id/legRightExtension"
android:background="#drawable/left_inactive"
android:layout_marginTop="142dp"
android:layout_marginLeft="100dp" />
</RelativeLayout>
</FrameLayout>
Any help is greatly appreciated.
Edit: I've also tried the relative layout existing on it's own, which gives me the same results overall:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fullscreen_content_controls_a"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background_buttons">
<ImageView
android:id="#+id/seatView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/seat"
android:layout_marginTop="60dp"
android:layout_marginBottom="60dp"
android:layout_marginLeft="245dp"
/>
<ImageButton
android:layout_width="124dp"
android:layout_height="75dp"
android:text="Seat Back Forward"
android:id="#+id/seatBackForward"
android:background="#drawable/left_inactive"
android:layout_marginTop="266dp"
android:layout_marginStart="38dp" />
<Button
android:layout_width="124dp"
android:layout_height="75dp"
android:text="Seat Back Forward"
android:id="#+id/legRightExtension"
android:background="#drawable/left_inactive"
android:layout_marginTop="142dp"
android:layout_marginLeft="100dp" />
</RelativeLayout>
I had a similar problem and someone suggested using this library - https://github.com/intuit/sdp . It provides units, that are automatically scaled across devices with different screen characteristics. Hope it helps :)

Making android support all screen sizes

I feel like I'm the only one lost here. Everyone seems to be fine with using DP to make apps work across multiple screen sizes. For me, whenever I load up another screen, the alignment will never be the scale properly.
However, if I use android:weight everything will scale fine across all devices. The problem I have with android weight for everything is that it doesn't always want to resize images well into layouts, not to mention the warnings I'll get for using nested weights.
One solution I see is creating a new screen size for each possible screen sizes out there. Is this what everyone else does? At first I thought we'd have to only create the x-large, small, etc layouts only to find that even these don't cope for various screen sizes (even the nexus 7 doesn't fall well into any of these categories).
Sample code
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:background="#drawable/layout_border"
android:padding="10dp" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:contentDescription="#string/app_name"
android:src="#drawable/yg" />
<ProgressBar
android:id="#+id/progressBar2"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView1"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/imageView1"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:progress="50" />
<TextView
android:id="#+id/textView1"
style="#style/NormalFont"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/progressBar2"
android:layout_alignLeft="#+id/progressBar2"
android:layout_marginLeft="36dp"
android:text="#string/exercise_percent" />
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="100dip"
android:layout_height="100dip"
android:layout_above="#+id/textView1"
android:layout_toRightOf="#+id/imageView1"
android:adjustViewBounds="true"
android:contentDescription="#string/app_name"
android:background="#drawable/start"
android:onClick="meditateTask" />
</RelativeLayout>
For example, here the imagebutton I have will be out of place on every new screen size.
You can create same layout for all screen sizes, small, normal, large and x large.
How can you do that: Make new XML layout file in layout folder, make it so it has same name as the layout you want to modify to fit for all screen sizes. Click next, and there will be some options shown, find Size and insert it. Then you will be able to chose which screen size you want.
And when launched, system will chose best screen size for device.
Repeat for all 4 screen sizes. Hope this helps

What is a correct way to place image over ImageView?

I'm novice in android development and still can't understand fully how sizing works with different layouts. I want to place a preview of the book into this template:
I've tried to implement it using FrameLayout. The idea is that the center of preview image will be exactly where the center of the png background is. Here is the code:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".5" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/book_frame" />
<ImageView
android:id="#+id/previewImage"
android:layout_width="83dp"
android:layout_height="83dp"
android:layout_gravity="center_vertical|center_horizontal"
android:src="#drawable/abs__ab_bottom_solid_dark_holo" />
</FrameLayout>
The result in layout builder look exactly like I want it to be:
On real phone it is different:
I think on other resolutions it will also differ from both variants. So my question is how to synchronize these images so after any resizing and distortions the preview will fit the cover correctly?
Possible solution would be to remove border from image and place it on previewImage instead. But there are several similar usecases in application where the border can't be removed, so I'd like to find out a universal solution for all of them.
You have your answer in your question.
What happening in your case image size matter for different screen resolution.
Hard-coded things always gives weird result in your case
android:layout_width="83dp"
android:layout_height="83dp" this piece of code.
Check this link this will guide you to manage drawables for different screens.
and here is another link
So the suitable solution for me was to separate border of inner image into its own ImageView, insert it into layout over the photo and add 1dp padding to the photo.
The layout become like this:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".5" >
<ImageView
android:id="#+id/bookFrame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal"
android:src="#drawable/book_frame" />
<ImageView
android:id="#+id/previewImage"
android:layout_width="83dp"
android:layout_height="83dp"
android:layout_gravity="center_vertical|center_horizontal"
android:padding="1dp"
android:scaleType="centerCrop"
android:src="#drawable/abs__ab_bottom_solid_dark_holo" />
<ImageView
android:id="#+id/previewBorder"
android:layout_width="83dp"
android:layout_height="83dp"
android:layout_gravity="center_vertical|center_horizontal"
android:src="#drawable/preview_border" />
</FrameLayout>

Android layout mis-stretched on a small device

I am developing an application for android. My main layout is a RelativeLayout.
When I'm opening the app for debug within a large-screen emulator, everything works fine.
But when I open it on a QVGA device, I see al the layout distorted.
Do I actually need to make a new layout for every screen size? I have seen at some places that android can automatically stretch everything to fit the layout...
Developer.android.com says:
By default, Android resizes your application layout to fit the current device screen.
(http://developer.android.com/guide/practices/screens_support.html)
Could you please help me figure out why a layout would look distorted ion a small device?
As you can see the images do get stretched, but the layout is not displayed well.
Thanks in advance!
Big Screen Image http://www.interload.co.il/upload/6549026.png
Small Screen Image http://www.interload.co.il/upload/9617759.png
Edit: XML code of the problematic page.
All the graphics are in "drawable-hdpi" folder, but again, the problem is not with the images themselves, but with the layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background" xmlns:android1="http://schemas.android.com/apk/res/android">
<ImageView
android:id="#+id/selectionHead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:src="#drawable/header" />
<ImageView
android:id="#+id/chooseFormatTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/selectionHead"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:src="#drawable/step1_choose_format" />
<ImageView
android:id="#+id/videoBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="42dp"
android:onClick="VideoClick"
android:src="#drawable/step1_video" />
<ImageView
android:id="#+id/orTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/videoBtn"
android:layout_centerHorizontal="true"
android:layout_marginBottom="19dp"
android:src="#drawable/step1_or" />
<ImageView
android:id="#+id/audioBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/orTxt"
android:layout_alignLeft="#+id/videoBtn"
android:layout_marginBottom="22dp"
android:layout_centerHorizontal="true"
android:onClick="AudioClick"
android:src="#drawable/step1_audio" />
<ImageView
android1:id="#+id/step1Share"
android1:layout_width="wrap_content"
android1:layout_height="wrap_content"
android1:layout_alignBottom="#+id/selectionHead"
android1:layout_alignParentRight="true"
android:layout_marginBottom="10dp"
android:layout_marginRight="5dp"
android1:src="#drawable/share" />
</RelativeLayout>
Do I actually need to make a new layout for every screen size?
You need to make a new layout when your existing layouts do not work and you elect to make a new layout instead of solving the problem in other ways.
Could you please help me figure out why a layout would look distorted ion a small device?
Your layout is perfectly fine, insofar as it is doing precisely what you told it to do:
The video button is 42dp above the bottom of the layout
The "or" line is 19dp above the video button
The audio button is 22dp above the "or" line
That is 83dp plus the sizes of the various images, which clearly makes it too tall.
If that is not what you want it to do on a small screen, either:
Come up with a different layout for -small devices, or
Use dimension resources instead of hard-coded values, and use different values for those dimension for -small devices, or
...

Can't support multiple screen resolution

I'm struggling to finish my Android app, but I'm having some problems with the UI. My problem is very basic, I've developed the UI using the default AVD when using AVD manager in Eclipse (HVGA, with a density of 160 dpi), and when I execute the app I see it as I designed, but if I change the target device (i.e. WVGA or QVGA) all the components in the layout are in a different position than the original. As far as I saw in the recommendations for support multiple screens, I should not use AbsoluteLayouts, in fact I'm using RelativeLayouts, I'm not using "px" for the dimensions (or positions), just "wrap_content" or "fill_parent", and in case I need an specific position I'm using "dp" (tested too with "sp"), also I've scaled the images for ldpi (0.75x), and still have the issue (not a particular screen, the hole app) ...so, my question is, is there any other UI tip that I'm missing?.
I'm putting a sample code and the results that I observe when testing it with a HVGA AVD (bigger image) and with a QVGA AVD. As you can see, the position of the yellow/green squares is different, as well as the size of the last row of images.
PS: I'm using a TabLayout also, so the background is loaded through code (tabHost.setBackgroundDrawable(getResources().getDrawable(R.drawable.background1)))
Any help will be appreciated.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/row1"
android:layout_centerHorizontal="true"
android:layout_marginTop="140dp"
>
<ImageView
android:id="#+id/btn1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:clickable="true"
android:onClick="method1"
android:src="#drawable/button1"
/>
<ImageView
android:id="#+id/btn2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:clickable="true"
android:onClick="method1"
android:src="#drawable/button2"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="#id/row1"
android:layout_centerHorizontal="true"
>
<ImageView
android:id="#+id/btn3"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:clickable="true"
android:onClick="method1"
android:src="#drawable/button3"
/>
<ImageView
android:id="#+id/btn4"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:clickable="true"
android:onClick="method1"
android:src="#drawable/button4"
/>
</LinearLayout>
</RelativeLayout>
Your layout looks fine to me, except for having that white box title on the background as it will make more difficult to put things in their position. Also, RelativeLayout does not have orientation but that is ignored.
In the bigger screenshot it looks like there is more space between the white box and the top of the screen. What it does not make sense to me is the different size in the second row. Are you 100% sure you are loading the correct images in the smaller screenshot?
You need to create different layout for diff. resolution i.e for large screen use layout-large folder..
I hope this link help to you.
Did you follow the steps given on the developer site to make ur app to support multiple screens?

Categories

Resources