Can someone explain how this weightsum work? and why - android

When i check the design for this code. this WeightSum act totally opposite the way i want. when i set my button weightSum for 70 it takes 30 (total weightSum is 100) vise-versa.
<LinearLayout
android:weightSum="100"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_weight="70"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button" />
<ToggleButton
android:layout_weight="30"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ToggleButton" />
</LinearLayout>

So android:weightSum defines the maximum weight sum of Layout, and it is calculate total sum of the layout_weight of all the its children views.
Example:- a LinearLayout having 3 Views(Which can be anything). Now you want to show 3 views equally in screen. So need to put layout_weight to views 1 and your weightSum is 3.
<LinearLayout
android:weightSum="100"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<View
android:layout_weight="70"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button" />
<View
android:layout_weight="30"
android:layout_width="fill_parent"
android:layout_height="0dp`enter code here`"
android:text="ToggleButton" />
</LinearLayout>
or You can also put your android:layout_weight in points also like below :-
<LinearLayout
android:weightSum="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<View
android:layout_weight=".7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button" />
<View
android:layout_weight=".3"
android:layout_width="fill_parent"
android:layout_height="0dp`enter code here`"
android:text="ToggleButton" />
</LinearLayout>
Remember 3 thing before use android:weightSum :-
set the android:layout_width of the children to "0dp"
set the android:weightSum of the parent (edit: as Jason Moore noticed, this attribute is optional, because by default it is set to
the children's layout_weight sum)
set the android:layout_weight of each child proportionally (e.g. weightSum="5", three children: layout_weight="1", layout_weight="3",
layout_weight="1")

You need set android:layout_width="0dp" of Button and ToggleButton.

you have set children view's width=0 if LinearLayout orientation is horizontal and height = 0 if orientation is vertical
I have made changes to your code, please refer :)
<LinearLayout
android:weightSum="100"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_weight="70"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Button" />
<ToggleButton
android:layout_weight="30"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="ToggleButton" />
</LinearLayout>
It works on percentage basis, When you want to make your views' height and width to occupy certain percentage of its parent then weights is the solution
e.g. if weightSum = 1 children can be of weight_layout .30 and.60. So basically addition of children's' layout_weight should be equals to weightSum of their parent (or less in WRT use cases)

In order to make it work well, as others have pointed, the width (or height, if the LinearLayout orientation was vertical) should be 0 (px or dp, whatever you wish, as it's still 0) for the children that have a weight.
About explanation of how it works, if not all had weight, the remaining one would be spread to them.
In your case, you don't have to set weightSum at all, because you've already set the weight for each of them (70+30 is indeed 100).
What it will do (after the needed changes), is set the first View to have a width that's 30% of the width of the parent, and the second view with 70% of the width of the parent.

based orientation, you should set layout_height or layout_width of parent layout to 0dp for correct behavior of weightsum.

Related

Cannot auto scale childs in a LinearLayout using weight 1 and width 0 in android

I have 12 textviews in a linear layout which is included in a relative layout, and I use for each child width=0 and weight=1 but nothing happens. Shouldnt be stretch to fit width? This is my layout. I use this for a drag and drop situation.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="2dp"
android:id="#+id/ChoicesLayout"
android:weightSum="12">
<TextView
android:layout_width="0dp"
android:layout_height="45dp"
android:id="#+id/txtChoice1"
android:gravity="center"
android:textStyle="bold"
android:background="#color/DarkPrimary"
android:layout_margin="2dp"
android:textSize="18sp"
android:layout_weight="1"
android:elevation="5dp"/>
........
</LinearLayout>
Well the answer is the following:
Because I was controlling the Textview if it was visible or not, I should have placed View.GONE and not View.Invisible in
TextView.setVisibility(View.GONE)
With invisible there was no space to auto scale

Android: ImageView next to TextView not showing

I have a TextView and ImageView in a ListView row, positioned next to each other. However, the ImageView doesn't show up at all, and doesn't register clicks either. This is the XML code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:text="text"
android:layout_width="320dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_centerVertical="true"
android:padding="10dp" />
<ImageView
android:id="#+id/imageView"
android:clickable="true"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/textView"
android:src="#drawable/ic_action"/>
</RelativeLayout>
The problem seems to lie in the layout_toRightOf line, if I remove it, the ImageView is shown, but in the wrong place. But I don't understand why it's causing a problem. What am I missing?
The issue is that the TextView is pushing the ImageView off the screen.
You can fix this using a LinearLayout and android:layout_weight
eg:
<?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">
<TextView
android:id="#+id/textView"
android:text="text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="10dp"
android:layout_centerVertical="true"
android:padding="10dp" />
<ImageView
android:id="#+id/imageView"
android:clickable="true"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_centerVertical="true"
android:layout_toRightOf="#id/textView"
android:src="#drawable/ic_action"/>
</LinearLayout>
More info on the layout_weight attribute:
This attribute assigns an "importance" value to a view in terms of how much space it should occupy on the screen. A larger weight value allows it to expand to fill any remaining space in the parent view. Child views can specify a weight value, and then any remaining space in the view group is assigned to children in the proportion of their declared weight. Default weight is zero.
For example, if there are three text fields and two of them declare a weight of 1, while the other is given no weight, the third text field without weight will not grow and will only occupy the area required by its content. The other two will expand equally to fill the space remaining after all three fields are measured. If the third field is then given a weight of 2 (instead of 0), then it is now declared more important than both the others, so it gets half the total remaining space, while the first two share the rest equally.
You need to use LinearLayout with weight.. if you set fixed width and the size of the phone is small, it will either stretch out of the screen.
//do linearlayout with orientation horizontal
<LinearLayout
...
orientation = "horizontal"
...
>
<TextView
....
android:layout_width="0dp"
android:layout_weight="1"
...
/>
<Button
....
android:layout_width="wrap_content"
...
/>
</LinearLayout>
Play with android:layout_weight, you will understand

Android - how can I change my 2-column layout to have dynamic widths?

I currently have a 2 column layout which looks like this:
<TextView android:id="#+id/TRAIN_CELL"
android:layout_width="275dip"
android:layout_height="wrap_content"
android:textSize="16sp"/>
<TextView android:id="#+id/TO_CELL"
android:layout_width="25dip"
android:textSize="20sp"
android:textStyle="bold"
android:gravity="center"
android:textColor="#color/light_best_blue"
android:layout_height="wrap_content"
android:layout_weight="1"/>
But with this approach I just hardcode the widths, and I am not sure what happens on wider on narrower screens. Is there a way to adjust this to use percentages of the width?
Thanks!
You can't specify width, or height using percentages, but there's something that is similar - weightSum and layout_weight. If you for example what your View to have width half of a screen, you have to do it like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:weightSum="1.0">
<View
android:id="#+id/view"
android:layout_height="wrap_content"
android:layout_weight=".5"
android:layout_width="0dip" />
</LinearLayout>
As you can see, the container of a View (LinearLayout) has set android:weightSum to 1.0 which means that 1.0 will be 100% of it's width/height. Then if you specify android:layout_weight for View inside this container to for example .5 and set it's width or height to 0dp (this part is very important as if you miss it, the View will use it's specified value instead of calculated one according to weights) it will receive 50% value of it's container's width/height.
android:layout_weight="1/2/3/4/5/..." will be your new friend ;-)
Do not forget to also use android:layout_width="0dip"

LinearLayout weights

I have two linear layouts that have the same width - one with two children and one with three. I'm trying to make the last two children the same width but I can't wrap my head around why Android behaves this way. I finally got it to look the way I want it to with the following weights:
Can anyone explain to me why this is working out this way?
I tried to do some simple math to figure out why. I'm guessing it's the sum of weights, minus the weight of the child, divided by the sum of weights, times the width of the parent. So:
sum = 1 + 6
((sum - 6) / sum) * W = 14.3% * W
I tried the same algorithm for the second row but it was totally off:
sum = 1 + 1 + 1.5
((sum - 1.5) / sum) * W = 57.1% * W
UPDATE
The above is true only when the child widths are set to match_parent. Setting width to 0, or 0dp, actually behaves as expected - greater weights lead to more space allocated for the child. The algorithm makes a little more sense now and works as expected for both rows.
sum = 1 + 6
(1 / sum) * W = 14.3% * W
Is the former behavior for weights with child widths set to match_parent by design? If so, what is the approximate algorithm for calculating the width of the children?
You can specify weightSum attribute for your LinearLayout in XML to let's say 1 for your first layout. Then your first 2 TextViews would get approx 0.9 and 0.1 weights (like 90% and 10%)
The same thing needs to be applied to the second LinearLayout. Something like:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1"
android:background="#FF0000FF" >
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=".9"
android:layout_margin="3dp"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:layout_margin="3dp"
android:background="#FFFFFFFF"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:weightSum="1"
android:background="#FF0000FF" >
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:layout_weight=".45"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=".45"
android:layout_margin="3dp"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight=".1"
android:layout_margin="3dp"
android:background="#FFFFFFFF"
android:text="TextView" />
</LinearLayout>
BTW, don't forget to set your width attributes to 0dip
First:
Based on the look of your layout, it looks like you'd want to use a GridLayout instead of two LinearLayouts.
Back to your question:
Don't set our layout_width to wrap_content (and especially not match_parent!) in your case.
Set the layout_width to 0dp and let the layout_weight attribute distribute the available horzontal space.
The layout_weight attribute distributes/adds additional space to the specified layout_width (or layout_height for vertical oriented LinearLayouts). If you want only the layout_weight to contribute to the spacing, set layout_width to 0dp (layout_height to 0dp in case of vertically oriented LinearLayout).
Try this first and see if this behaves more to what you'd like and expect.
Try this example (where the grids are ratio 3:3:1):
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FF0000FF" >
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="6"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFFFF"
android:text="TextView" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:background="#FF0000FF" >
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="#FFFFFFFF"
android:text="TextView" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#FFFFFFFF"
android:text="TextView" />
</LinearLayout>
According to your picture - weights are incorrect. E.g first "row": you have set first TextView with weight '1' and second weight is '6' - this means that second TextView will have more space - 6/7 of all layout width and first TextView have only 1/7. To simplify calculations imagine total width as 100(%) and divide them between views according to proportions which you want to give them.

Proper way to divide into 4 pieces an android layout

what I want to achieve is, divide the rows layout described in picture below. what should I do to achieve dividing the row into 3 exactly same size and 1 unknown size? X are same size and i dont know and dont want to specify if its not necessary...
EDIT: buttons are on the left , center, and right.
Use a LinearLayout inside a RelativeLayout. Put 3 items inside the LinearLayout and give them the same weight. Put the unknown item to the right of the LinearLayout with the help of RelativeLayout.
Left elements will align themselves according to the right-one's width.
Here's the code: https://gist.github.com/3772838
And here 2 screenshots with different sized right most elements:
http://goo.gl/Nezmn
http://goo.gl/XbQwL
Kolay gelsin =)
You can use android:layout_weight to distribute extra space proportionally. You want the three left buttons to absorb all the extra width, so the right (fourth) button should have the default weight of 0. Since you also want them to have the same width, the easiest is to assign them a width of 0dp and give them all the same weight:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Does your extreme left size has a minimum width ?
If so, you should use a LinearLayout with horizontal orientation.
It could contains 2 LinearLayout, one which contains 3 Views (your Buttons) with 0 width and with 1 weight each and the other LinearLayout has a minimumWidth set.
Instead of the marginRight, you could specify a width for the first layout.
Ted Hopp get it right ;)
<?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:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:id="#+id/rlayoutParent">
<RelativeLayout
android:layout_width="wrap_content"
android:id="#+id/rlayoutButtons" android:layout_height="wrap_content">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" android:layout_toRightOf="#+id/button1"/>
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" android:layout_toRightOf="#+id/button2"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/rlayoutOther"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/rlayoutButtons" android:gravity="right">
<Button
android:id="#+id/button4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button" />
</RelativeLayout>
</RelativeLayout>
you cab use the layout_weight attribute. give all the x layout the same weight and the question mark a diffrent weight until the screen will devide as u like

Categories

Resources