When I have the following, it shows top layout with four colors has much smaller area than the bottom layout area.
According to this documentation, when you add more to layout_weight, it should increase the area, but it decreases in the code.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="4">
<TextView
android:text="red"
android:gravity="center_horizontal"
android:background="#aa0000"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="3"/>
<TextView
android:text="green"
android:gravity="center_horizontal"
android:background="#00aa00"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="blue"
android:gravity="center_horizontal"
android:background="#0000aa"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="yellow"
android:gravity="center_horizontal"
android:background="#aaaa00"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:text="row one"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:text="row two"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:text="row three"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<TextView
android:text="row four"
android:textSize="15pt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
I had the same problem. The trick is not to use "wrap_content" or "fill_parent" for the controls you are setting a weight to. Instead set the layout_height to 0px (when inside a vertical layout) and then the child controls will get proportioned per the weight values.
If you get the error as
error
Suspicious size: this will make the view invisible, probably intended
for layout ...
remember to set the correct parameter on
android:orientation in parent
If you are using fill_parent in a LinearLayout the layout will take as much space as possible and all layout items defined later will have to deal with the space left.
If you set the height of both of you LinearLayouts to wrap_content the weight should work as documented.
I know this is late but hopefully it helps people:
Use android:weightSum on the parent. Here is a link to the dev docs.
http://developer.android.com/reference/android/widget/LinearLayout.html#attr_android:weightSum
Use android:weightSum of 1.0 on the parent and then use 0.x on the child views with android:layout_weight in order for them to use that ratio of space.
Building on what Janusz said, if you use fill_parent, you can then set android:layout_weight to "split" the "full area" between multiple layout items.
The layout_weight doesn't increase the area, it increases it "right" to the area. but it's also relative to the parent. If you have a parent with a layout_height=fill_parent, with a layout_weight=0 and the parent has a sibling with the same, setting layout_weight=1 to one of the children does not affect the parent.
Both the parent, and the sibling, would take up 50% of the available area that they can fill.
The solution is to set layout_height to 0px when you use layout_weight.
But why do you observe this apparently strange/inversed behavior ?
Shortly : the remaining space is negative and so the child with weight 4 receive more negative space and it's height is more reduced.
Details :
Assume that the height of your parent vertical layout is 100 pixels.
Layout height on each child is fill_parent (i.e. each child is also 100 pixels height)
The total height of all child = 2*100 pixels
The remaining height = 100 - (2*100) = -100 pixels (it is negative)
Now, let's distribute this remaining height between child. The first one will receive the biggest part : 80% (i.e. -100*4/(4+1)). The second child receive 20% (i.e. -100*1/(4+1))
Now compute the resulting height :
child 1 : 100 + (-80) = 20px
child 2 : 100 + (-20) = 80px
Nothing strange here, only mathematics. Just be aware that remaining space can be negative ! (or set the height explicitly at 0 as it is recommended)
In linear layout properties change the layout width to "fill_parent" instead of "wrap_content"
hope it helps.
If the orientation of linearlayout is vertical,then set layout_height as 0dp. In case of horizontal layout set layout_width as 0dp.
If we do not follow above rules,the view tends to take up space as per specified attributes and hence the alignment is not as per expectation.
Related
I wanted to represent a table. I have a parent container in a LinearLayout with vertical orientation and each row is further represented by a LinearLayout with horizontal orientation & weight of 100. I have used weight to ensure that the left side column and right side columns get 50% of screen width. But the columns on the right side are not properly aligned for some rows. What can I do to properly align them as in a table?
This is how my code appears for each LinearLayout row represented below
<LinearLayout
android:orientation="horizontal"
android:weightSum="100"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_weight="50"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BOM ID"
android:id="#+id/tvBOMID" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/etBOMID"
android:hint="BOM ID"
android:layout_weight="50" />
</LinearLayout>
Simply give 1-1 equal weight to TextView,EditText and set width as 0dp :
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="BOM ID"
android:id="#+id/tvBOMID" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/etBOMID"
android:hint="BOM ID"
android:layout_weight="1" />
</LinearLayout>
To fix this, change the layout_width's to 0dp for the Layouts with weights, everything else looks fine. Any time you use a weight, set the width or height (whichever one is determined by the weight) to 0dp.
in Android we have veryy good concept of Weight.
we give Weight To only in LinearLayout.
and We give Weight To the Layout Horizontally as well as vertical means in simple way we give weight layout height and Width.
in Weight You want To give a 0dp for the height or width which you want to give a weight.if you not give 0dp than its not affect to layout.
Widht wise Weight...
give 1 1 weight so textview takes 50 %and edittext 50% of total width of parent layout.
give 1 2 weight so textview takes 33.33% and editext takes 66.66% total width of parent layout.
give 1 3 weight so textview takes 25% and edittext takes 75% total width of parent layout.
Height wise Weight....
give 1 1 weight so textview takes 50% and edittext 50% of total Height of parent layout.
give 1 2 weight so textview takes 33.33% and editext takes 66.66% total Height of parent layout.
give 1 3 weight so textview takes 25% and edittext takes 75% total Height of parent layout.
in your case You want Width 0dp and weight is 1.
**You just add this code**
android:layout_weight="1"
android:layout_width="0dp"
below the code
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="BOM ID"
android:id="#+id/tvBOMID" />
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/etBOMID"
android:hint="BOM ID"
android:layout_weight="1" />
</LinearLayout>
just change :
android:layout_width="wrap_content"
to :
android:layout_width="fill_parent"
in textview and edittext.
In this layout definition:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="7"
android:id="topLayout"
android:background="#android:color/holo_green_light">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_weight="2"
android:id="bottomLayout"
android:background="#android:color/holo_orange_light">
</LinearLayout>
</LinearLayout>
I don't understand why the named "bottomLayout" is higher than the topLayout. You can see a commented screenshot of the result in Android Studio.
First of all fix your xml and change layout_height to 0dp.This is because your are using weights to manage height and at the same time your are instructing it to fill parent.
Second, if you'll experiment by giving weights as 1 for each you'll notice that both the layouts are now divided equally.What I assume is that weight is the calculation of available space that's left after adding the view i.e The weight is calculated according to the available space.
Check in your preview by clicking on the outline for any overflowing of layouts out of screen, you might find that some part of your layout is out of screen. To get some clarity either use your weights according to percentage for example instead of giving in 2 and 7 try with 0.2 and 0.8, this will balance the weigts. Or you can use the attribute "weight_sum" to declare total available weight and then distribute it evenly, for example with weight_sum 100 you can follow a percentage based approach.
See this link for further clarity.
LinearLayout children are laid out in order they are declared.
layout_weight mechanism only distributes any remaining space to elements in proportion to their weight, it doesn't affect the ordering.
This is unlike some other environments where a "weight" parameter affects an item's position in a container.
If you make your code to like this then you can find solution
<LinearLayout
android:![enter image description here][1]orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="7"
android:id="topLayout"
android:background="#android:color/holo_green_light">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="3"
android:id="bottomLayout">
<Button
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="b"
android:id="#+id/button4"
android:layout_gravity="center"
android:background="#android:color/holo_orange_light"/>
</LinearLayout>
if you want to use layout_weight in linearlayout then you have to add weightSum in parent LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10"
android:orientation="vertical"
>
<--70% of free space in parent LinearLayout-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="7"
>
</LinearLayout>
<--30% of free space in parent LinearLayout-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
>
</LinearLayout>
</LinearLayout>
in xml comments i wrote 70% of free space in parent LinearLayout
if you add some layout with exact height then both your linearlayouts will occupy 70% and 30% of left height in that particular linearlayout
for example if height of your parent linearlayout is 100dp
your child layouts will be drawn first one 70dp and the second one will be 30dp tall
but if you add some imageview with height 50dp then your first child linearlayout will be about 35dp tall and 15dp for second one
I have this as part of my layout:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dip"
android:orientation="horizontal"
android:layout_weight="0.15">
<TextView
android:id="#+id/question_text"
android:layout_width="0dip"
android:layout_height="fill_parent" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="#string/score_label" />
<TextView
android:id="#+id/score_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right" />
</LinearLayout>
The first TextView is empty at the beginning of the application. Its content is changed dynamically. This makes it occupy zero space so that the second TextView is aligned to the left, even though its layout_gravity is set to right.
How can I make it occupy a fixed width, without taking the contents into account?
I thought about using layout_weight, but I know the recommendation is against using nested weights (the parent ViewGroup has a layout_weight attribute). Maybe I should use a RelativeLayout?
Thanks for any suggestions.
I solved a similar problem using the attribute android:ems="<some number>" on the TextView. An "ems" is the width of the character "M". This attribute makes the TextView exactly the given no. of ems wide.
http://developer.android.com/reference/android/widget/TextView.html
You have all of your TextViews width set to android:layout_width="wrap_content" which means that if there's nothing in there it will have no width. You need to set that to either "match_parent" which will make it the same width as it's parent container or set it to a fixed value, something like android:layout_width="100dp".
I've seen several examples that use
android:layout_height="0px" or "0dip" but i do not understand the impact of this. It seems that would make the layout 0 pixels tall. Is the value mitigated but some other factor like 'weight' or the height of any parent views?
Yep you are right about the weight, when you want the width or height to be controlled by weight its convention to set that value to 0dip and let the weight control the actual value. Although I am pretty sure 0 is just arbitrary here you could put anything but putting 0 makes your intention more clear.
When using a LinearLayout if you set the layout_weight to a non-zero value and set the layout_height (or layout_width) to 0px or 0dip then the LinearLayout distributes any unassigned space along the appropriate axis based on the weights. So for example, if you look at the layout below the View with id *gestures_overlay* it has layout_height 0dip and layout_weight 1 so the parent LinearLayout stretches it to fill the available vertical space between the 2 surrounding LinearLayouts. If there was another View with the same 0dip layout_height and a layout_weight value then they would share the vertical space based on their weight values.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="6dip"
android:text="#string/prompt_gesture_name"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/gesture_name"
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="wrap_content"
android:maxLength="40"
android:singleLine="true" />
</LinearLayout>
<android.gesture.GestureOverlayView
android:id="#+id/gestures_overlay"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1.0"
android:gestureStrokeType="multiple" />
<LinearLayout
style="#android:style/ButtonBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/done"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:enabled="false"
android:onClick="addGesture"
android:text="#string/button_done" />
<Button
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="cancelGesture"
android:text="#string/button_discard" />
</LinearLayout>
</LinearLayout>
A relevant example from the official developer docs (http://developer.android.com/guide/topics/ui/layout/linear.html):
Equally weighted children
To create a linear layout in which each child uses the same amount of space on the screen, set the android:layout_height of each view to "0dp" (for a vertical layout) or the android:layout_width of each view to "0dp" (for a horizontal layout). Then set the android:layout_weight of each view to "1".
When we have to assign equal weight to the different view in LINEAR LAYOUT
then we assign either layout/width = 0dp(for horizontal orientation) or layout/height = 0dp(for vertical orientation) and set View /weight ==1 for every view inside that Linear Layout.
Advantage::::
-- on assigning width or height to 0dp then it have no impact and due to weight==1 all the view occupies same space and covered the whole screen size.
friends,
i have written following layout code and buttons to be displayed on screen equally but it not seems to work any one guide me what mistake am i doing?
![<?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"
>
<LinearLayout
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="#color/color_panel_background"
>
<ImageButton
android:layout_height="wrap_content"
android:id="#+id/currentLocation"
android:layout_weight="1"
android:layout_width="fill_parent"
android:src="#drawable/current_location_icon"
/>
<ImageButton
android:layout_height="wrap_content"
android:id="#+id/searchCity"
android:layout_weight="1"
android:layout_width="fill_parent"
android:src="#drawable/search_icon"
/>
<ImageButton
android:layout_height="wrap_content"
android:id="#+id/home"
android:layout_weight="1"
android:layout_width="fill_parent"
android:src="#drawable/home_icon"
/>
</LinearLayout>
</RelativeLayout>][2]
The drawable for the middle button is obviously bigger than the other two. You set the height of the buttons with wrap_content, so the middle button gets bigger. Weight has nothing to do with this. Its only defining how much space the item takes when you use fill_parent.
Easiest way to fix this is either changing the layout_height to a fixed value (use dp as unit)
or change the size of your drawables making the images all the same size to begin with.
Thumbs up for the way you asked the question. Screenshot and relevant code. Wish everybody would do that :)
Change android:layout_height from "wrap_content" to some constant if you want them to have equal height.
change your linear layout height to some constant and
change object layout_height within the linear layout to fill_parent
in Horizontal: if you set weight for child view then set with = 0dp
in Vertical: if you set weight for child view then set height = 0dp