Android logic behind weightsum - android

So I have this XML code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutOuter"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="3.0"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1.0"
>
<Gallery
android:id="#+id/galleryMain"
android:layout_width="match_parent"
android:layout_height="90dp">
</Gallery>
<LinearLayout
android:id="#+id/linearLayoutInner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#layout/gallery_image_background"
/>
</LinearLayout>
<TextView
android:id="#+id/galleryTextView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2.0"
>
</TextView>
</LinearLayout>
Currently it sizes correctly, but I don't think that can be right.
The LinearLayout that gets 1.0 out of 3.0 possible weight takes about 2/3 space.
The TextView that gets 2.0 out of 3.0 possible wight takes about 1/3 space.
Is above really how it is meant to work? It sizes like I want, but... Not sure I understand the logic behind it.

Is above really how it is meant to work?
Given the way you wrote it, yes, but that's why we usually don't write it that way. :-)
The easier-to-understand approach to weights and android:weightSum is to have the heights set to 0dp, not match_parent. Then, each child gets a proportion of the available space based on the weights.
So, to get your 2/3 and 1/3 split this way, you would have:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/linearLayoutOuter"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="3.0"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:layout_weight="2.0"
>
<Gallery
android:id="#+id/galleryMain"
android:layout_width="match_parent"
android:layout_height="90dp">
</Gallery>
<LinearLayout
android:id="#+id/linearLayoutInner"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#layout/gallery_image_background"
/>
</LinearLayout>
<TextView
android:id="#+id/galleryTextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"
>
</TextView>
</LinearLayout>
Note that:
You could go with integers here
You do not need android:weightSum in this case, as the sum of your weights already is that value. You would use android:weightSum in cases where the sum of your weights is less than the real total, indicating that some portion of the space should remain as whitespace and treated as such (by default, appearing after the children of the LinearLayout).

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".

How to set the percentage in screen of each fragment

I want to design a divided screen into two non equal parts in a landscape mode of screen. So, I thought automatically in using fragments. But the problem that I have encountered is that each fragment match the half of the screen. And that's not what I want exactly. What I want is a screen with two parts non equal in their width. I want something like this:
You can make use of the weight parameter.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
Please notice the weights used for the two LinearLayouts. The first one has a weight of 1 (it can occupy 1/4 th of the screen) and the second one 3 (it can occupy 3/4 th of the screen).
Just use this exact same concept for your fragments and maintain nay proportion as you wish.
Hope I could make myself clear.
Use weight parameter
<LinearLayout android:orientation="vertical" android:layout_height="fill_parent" android:layout_width="fill_parent">
<LinearLayout android:layout_weight="1" android:layout_height="fill_parent" android:layout_width="fill_parent"/>
<LinearLayout android:layout_weight="3" android:layout_height="fill_parent" android:layout_width="fill_parent"/>
</LinearLayout>
set Linear layout weight to achieve this...
<?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" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="2" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>

I have some problems with the XML layouts (android development).

I think I have some problems with a LinearLayout container. I do not know how to fix these problems:
I am a beginner to XML but I think the problem is in the second LinearLayout. I hope someone can help me out.
The code is here below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
**<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
andriod:orientation="horizontal" >
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>**
<Button
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
</LinearLayout>
The problem I see when reading your xml file is that inside the main LinearLayout you have 3 elements with the properties about the width and height as follows:
android:layout_height="match_parent"
android:layout_width="match_parent"
which means you expect the elements to fill entirely the main LinearLayout. This is not going to work. A linear layout has ordered not overlapping elements (RelativeLayout is there for that). Since the main LinearLayout is supposed to be oriented vertically, I suppose that for these three elements, you need to set the properties to match the whole width of main LinearLayout and to be wrapped vertically, by setting these values:
android:layout_height="wrap_content"
android:layout_width="match_parent"
You should apply these to the TextView, LinearLayout and Button elements of second level.
If you have overlapping imageviews try adding weights to them and/or changing the width to not match the parent and only wrapping the content.
please change andriod to android ( Line 14 )
Your posted code has a typo. Your fix might be as simple as replacing the line:
andriod:orientation="horizontal"
with:
android:orientation="horizontal"
Judging by the image you posted, I think you may have forgotten to add weights to occupy the free space in your Linearlayouts. Try this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
andriod:orientation="horizontal"
android:layout_weight="1" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</LinearLayout>
<Button
android:layout_height="wrap_content"
android:layout_width="match_parent"
/>
</LinearLayout>

How can you make your android application occupy only half of the screen?

I have a list, but it will occupy all the screen of the tablet. Is there a way to make it only occupy half , or 1/4 of the tablet screen?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_gravity="center_vertical"
android:layout_weight="1" />
</LinearLayout>
Add another blank view or the view that you want to place in another half. Set its layout weight to 0.5: android:layout_weight=".5".
Set android:layout_weight=".5" for ListView.
Note that setting layout_weight to .5, if there is a single view in a container would have no effect.
Good Luck!
You can use the following in your XML for vertical split of screen:
Here we are using weightsum and weight attributes.
You can adjust the weight property to get the desired results in terms of half or quarter etc.
<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="vertical"
android:weightSum="100" >
<RelativeLayout
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:background="#android:color/black" >
<!-- Your RelativeLayout Items -->
</RelativeLayout>
</LinearLayout>
In order to get the same in horizontal manner, the below would be useful:
<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:background="#android:color/darker_gray"
android:orientation="horizontal"
android:weightSum="100" >
<RelativeLayout
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50"
android:background="#android:color/black" >
<!-- Your RelativeLayout Items -->
</RelativeLayout>
</LinearLayout>
EDIT:
To display as widgets, You can refer tutorials here http://www.vogella.com/tutorials/AndroidWidgets/article.html and here http://www.tutorialspoint.com/android/android_widgets.htm

Android: top menu bar + scrollview?

I'm new with Android (used to develop with Visual Studio...) and so far I have a doubt with the layouts:
What I want to do is a layout with a bar at the top (just to put some button or extra information) and a scroll view that fills the rest of the screen.
This is the way I am doing it so far:
<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"
tools:context=".Home" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#android:color/white" >
<!-- I can put any button or text I want in here -->
</LinearLayout>
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"
android:background="#drawable/wallpaper" >
</ScrollView>
This is working as I expected, but my question is if I'm doing it the correct way or should I do it in a better way (most efficient).
Thanks in advance
Absolute positioning isn't recommended. For example, if you need to increase the height from 50dp to 100dp, you will have to change this value in several different places.
I know at least 2 ways to improve your layout.
1) Use features of RelativeLayout (android:layout_below="#id/linearLayout1" or its counterpart layout_above)
<RelativeLayout ...>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#android:color/white">
</LinearLayout>
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/linearLayout1"
android:fillViewport="true"
android:background="#drawable/wallpaper" >
</ScrollView>
</RelativeLayout>
2) Replace by LinearLayout (and use android:layout_weight="1.0")
<LinearLayout ...>
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#android:color/white">
</LinearLayout>
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
android:fillViewport="true"
android:background="#drawable/wallpaper" >
</ScrollView>
</LinearLayout>
The line android:layout_height="0dip" may look strange. Actually you can use match_parent, but Eclipse IDE highlights such line and recommends to use 0dip if you have specified android:layout_weight.
Also I added android:fillViewport="true" to your scrollview. It indicates that the content inside the scrollview will expand to the full height if it is necessary, you can read about this property here

Categories

Resources