Android: Layout proportional scale - android

I want to simulate microcontrolers screen (800x480) on android devices. Screen content is buttons, labels, graphic primitives(line, rect, ...), images.
What to do to fit layout (scale up/down) on all screens?
Here is layout xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="800px"
android:minHeight="480px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rootLayout"
android:gravity="center">
<LinearLayout
android:orientation="horizontal"
android:minWidth="800px"
android:minHeight="480px"
android:layout_width="800px"
android:layout_height="480px"
android:id="#+id/mainContainer">
<NSU.Droid.MyWindow
android:minWidth="714px"
android:layout_width="714px"
android:layout_height="match_parent"
android:id="#+id/mainWindow"
android:background="#drawable/window_shape"
android:layout_margin="1dp" />
<LinearLayout
android:minWidth="86px"
android:layout_width="86px"
android:layout_height="match_parent"
android:background="#drawable/sidewindow_shape"
android:layout_margin="1px"
android:scrollbars="none">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<NSU.Droid.SideWindow
android:orientation="vertical"
android:minWidth="86px"
android:layout_width="86px"
android:layout_height="wrap_content"
android:id="#+id/sideWindow"
android:scrollbars="none" />
</ScrollView>
</LinearLayout>
</LinearLayout>
NSU.Droid.MyWindow is RelativeLayout.
If px is used, simulated layout is too small, about 1/3 on my device screen. Changing px to dp does not help - view is too big, I can see about 2/3 of layout content.
How to scale layout and content proportionally?

Use match_parent for android:layour_width or android:layout_height attributes to fit screen with layout.
To make items sizes proportional, you can use android:layout_weight attribute in LinearLayout.
For example:
<LinearLayout
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="horizontal">
<FrameLayout android:layout_width="0dp" android:layout_height="match_parent"
android:background="#ff0000"
android:layout_weight="3" />
<FrameLayout android:layout_width="0dp" android:layout_height="match_parent"
android:background="#0000ff"
android:layout_weight="1" />
</LinearLayout>
If you have horizontal orientation of your LinearLayout, you should set android:layout_width attribute to 0dp to elements of this LinearLayout to which you want apply android:layout_weight attribute. If orientation of your LinearLayout is vertical then android:layout_height attribute should be set to 0dp.
The XML above should look like this:

Related

I don't understand how this is working (MATCH_PARENT at View with layout_weight)

When I set MATCH_PARENT for View + layout_weight the elements of the view behave strangely. Please can you explain why this is so. For example, here is the code on which to experiment. I can't understand the pattern. The less put the weight of the item, so it is more, however, it is unclear how many times.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="5"
tools:context=".MainActivity">
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F00"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F0F"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0FF"
android:orientation="horizontal">
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00F"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
Testing for Yellow layout: set layout_weight= 0.5 > large?? how much bigger? Did the elements shrink in size or were they thrown out of the parent?
<LinearLayout
android:layout_weight="0.5"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F00"
android:orientation="horizontal">
</LinearLayout>
Update, PS: I know how the layout will work with WRAP_CONTENT (or 0dp). If you set MATCH_PARENT + layout_weight, then we have a fixed element size regardless of the content, when WRAP_CONTENT does not guarantee a fixed size from the content (and if the content size is increased, the element will be stretched). I am only interested in the pattern MATCH_PARENT + layout_weight, because it guarantees the block size when the content size is exceeded.
The less put the weight of the item, so it is more...
The reason is because you are assigning android:layout_width as match_parent to all LinearLayout. To get android:layout_weight worked, you should set android:layout_width as 0.
First of all, give android:weightSum to the parent of the layouts.
Secondly, if you have layouts placed horizontally next to each other then set android:layout_width="0dp" for each element.
Similarly, for vertically aligned elements, give android:layout_height="0dp".

Android: nested linearlayouts error

I am trying to create, as a test, a row of three images (evenly spaced with a vertical orientation) in the top half of my screen. For some reason, android:layout_height="0dp" is giving me an error, saying it will make the view invisible. It is right of course, I can't see a thing. Why is that the case? I changed the weight to 1, so why isn't it expanding to take up the space available? Thanks!
<LinearLayout 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:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="#drawable/arches_utah"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="#drawable/blue_sea_mountains"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="#drawable/china_jungle"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
</LinearLayout>
The layout_weight on an element applies to the parent of said element. Since you parent element has a horizontal orientation, you can only use layout_weight paired with layout_width. If your root LinearLayout was a vertical then you could set the layout_height to be 0dp and use layout_weight instead.
Judging by your question, it sounds like you should be setting weights and height on the three elements within the first child LinearLayout.
The weight attribute needs to be specified on the same axis as the orientation of the parent. Since your parent LinearLayout has a horizontal orientation, the weight attribute works on the width, so you need layout_height="wrap_content" and layout_width="0dp" on the child LinearLayout.
So the problem is between your 2 LinearLayouts.
You have not closed your parent Linear Layout and layout width relate weight not height...You can also use weightSum like this...
<LinearLayout 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:orientation="horizontal"
android:weightSum="2" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="#drawable/arches_utah" />
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="#drawable/blue_sea_mountains" />
<ImageView
android:layout_width="match_parent"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="#drawable/china_jungle" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>

Element relative height in layout

I have seen that the width of an element can be set to a fraction of the screen width by using a relative layout (code below showing ONLY the relevant properties):
<LinearLayout>
<ImageView
android:layout_width="0dp"
android:layout_weight=".40" />
</imageView>
<TextView
android:layout_width="0dp"
android_layout_weight=".60" />
</LinearLayout>
But ... apparently this same trick can NOT be done for assigning proportional height of an element. Eclipse complains if I attempt to set a layout_height of 0dp. What should I do if I want an image with a caption, where the image takes up 40% of the screen height and the caption below gets 60% ?
You can indeed assign weights for both horizontal and vertical orientations of a LinearLayout.
Horizontal orientation example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".40" />
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight=".60" />
</LinearLayout>
Vertical orientation example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".40" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".60" />
</LinearLayout>
As an aside, it's useful to know that you don't have to specify floating point numbers for the weights. Android will simply sum up all of the weights and then divide by the total to get the percentage for each. So using 4 and 6 respectively for the layout_weights would have worked just as well.
Add android:orientation="vertical" to your layout and then set layout_height=0dp and weight to wanted values.
So:
<LinearLayout
android:orientation="vertical">
<ImageView
android:layout_height="0dp"
android:layout_weight=".40" />
</imageView>
<TextView
android:layout_height="0dp"
android_layout_weight=".60" />
</LinearLayout>

Android: Layout looks different on different devices

Hi I have an activity with an imageview and a row with buttons at the bottom.The buttons are added to the iconView layout programmatically.When I test my app on my HTC one the buttons are displayed correct.
Once I run it on a device with a smaller screen it is cropped i.e. only the top of the buttons is displayed.
How can I make my code device independent?
<?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:background="#000000"
android:orientation="horizontal" >
<LinearLayout
android:id="#+id/mainView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background2"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.95"
android:orientation="vertical"
android:paddingLeft="4dp"
android:paddingTop="4dp"
android:paddingRight="4dp"
android:paddingBottom="4dp"
android:src="#android:drawable/ic_menu_camera" />
<LinearLayout
android:id="#+id/iconView"
android:layout_weight="0.05"
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal" >
</LinearLayout>
</LinearLayout>
</LinearLayout>
Thanks in advance.
Try this layout:
<?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:background="#000000" >
<RelativeLayout
android:id="#+id/mainView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/background2" >
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:layout_above="#+id/iconView"
android:src="#android:drawable/ic_menu_camera" />
<LinearLayout
android:id="#+id/iconView"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:orientation="horizontal" />
</RelativeLayout>
</LinearLayout>
Try this
make the first view with android:layout_weight="1"
and the with a static height without the layout_weight, this should solve it
Unfortunately the solutions did not work. Eventually I changed my code and add the buttons in the xml, not programmatically. This works fine. I don't know why...
When adding button either programmatically or in XML layout, try to use LinearLayout as the parent for button and leverage the "weightsum" property of that LinearLayout.
When you're going to share the real state of screen's width or height equally between a number of views such as buttons or textview or ..., you can set "layout_weight" property on those controls. Notice that, this is only possible when using LinearLayouts.
What happens at the end is that the linearlayout's real estate is calculated and allocated according to each child's element's "layout_weight" value.
The example below shows how to put two buttons beside each other and make them fill the screen's width equally :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="2"
>
<Button
android:id="#+id/btn_left"
android:layout_width="0dp" // width is calculated by weight
android:layout_height= "wrap_content"
android:layout_weight="1" />
<Button
android:id="#+id/btn_right"
android:layout_width="0dp" // width is calculated by weight
android:layout_height= "wrap_content"
android:layout_weight="1" />
<LinearLayout/>

Height of child element as percentage of parent element

I have an EditText tag inside the LinearLayout with horizontal orientation, I want to make height of my EditText as percentage of parent LinearLayout's height. How can this be achieved?
Please don't suggest layout_weight attribute as it will be used to control child elements width not height.
You could write a custom layout that resizes its children to the correct percentages, which is probably the best solution.
Or you could use layout_weight and wrap the EditText in another LinearLayout, something like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:weightSum="2"
android:orientation="vertical">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="one"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="two"/>
</LinearLayout>
Percentages within a LinearLayout are very easy.
Give your view a weight
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:weightSum="2"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="0.5"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="0.25"
android:text="one"/>
</LinearLayout>
I've set the height of the two textViews to 0, but the layout_weight says to make one 50% of the LinearLayout and the other 25% the height of the layout.

Categories

Resources