Same size children in vertical LinearLayout - android

I have a LinearLayout with vertical orientation. All of the children's height is set to wrap_content. I would like to make all children have the same height, the height of the biggest child. Is this possible to do?

To distribute sub views evenly in LinearLayout, The official docs give a standard way:
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".

If you want to do to make that item follows its spaces, you can use, layout:weight
For example here,
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:orientation="vertical"/>
<LinearLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:orientation="vertical"
android:weight="1"/>
<LinearLayout
android:layout_height="0dp"
android:layout_width="match_parent"
android:orientation="vertical"
android:weight="1"/>
</LinearLayout>

Related

android:Why "layout_weight=1" makes the view align parent bottom in linearlayout? [duplicate]

This question already has answers here:
What does android:layout_weight mean?
(13 answers)
Closed 2 years ago.
The xml layout is like this:
<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="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bottom"/>
</LinearLayout>
And it turns out that the textview will be placed to the bottom of its parent.I think layout_weight is used to allocate unusesd space and it's very common to use layout_weight with code like :
android:layout_width="0dp"
But in this case,the first layout asks to occupy all spaces with:
android:layout_width="match_parent"
android:layout_height="match_parent
So how does layout weight work here?
PS:I have read this question: What does android:layout_weight mean? but I don't think it accounts for this question.
layout_weight specifies how much of the extra space in the layout to be allocated to the View.
The first linearlayout has already taken the whole space with attribute match_parent,why setting layout_weight enables the second view to showup at the bottom ?
I believe this is not the common usage of layout_weight.Hope somebody point out my mistake.
When you use layout_weight attribute it is used to calculate the weightage of child views of the single parent.
As you have not mentioned weight of all other views it's behaving wrong.
layout_weight is useful when you want your child views to be certain percentage of the parent view.
for example,
in parent view you need to mention:
android:weightSum="1"
So your parent view will have total weight as 1, and in both of the views you need to mention the:
android:layout_weight=".9" and android:layout_weight=".1"
so the first view will take 90%, and second view will take 10% of the space.
To be more clear Ideally the sum of weights of all the childs should be equal to the weightsum mentioned in parent, to it work as expected.
**And as you have provided android:layout_width,android:layout_height` of the textview, this is the mistake as it will make issue in the weight.
So to use weight attribute correctly you need to give other specs as 0dp in order to weight to apply successfully.**
Note: When you use weight other specs like android:layout_width,
android:layout_height should be set to 0dp.
To understand it practically, why don't you play around with below
layout:
Just Try to change the weight of linear_layout, text_view and you will see, how it's supposed to works ideally:
<?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"
android:weightSum="100" >
<LinearLayout
android:id="#+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:background="#android:color/holo_blue_bright" >
</LinearLayout>
<TextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="90"
android:background="#android:color/white"
android:text="bottom"
android:textColor="#android:color/black" />
</LinearLayout>
If you want to place your components in separate boxes in layout ,you should use LinearLayout.
You can define the manner of boxes place with orientation vertical or horizental.
You can define their size easily with layout_weight.
look here:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id=#+id/parent_linear>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="4">
</LinearLayout>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="bottom"/>
</LinearLayout>
parent_linear divides your layout in 2 parts(because you use 2 components) vertically. Now you can set weights to child's components width. So,(for TextView) you set android:layout_width="0dp" for its width and android:layout_weight="2" ..follow it for LinearLayout- .
The result of this is parent_layout divide itself into 6 parts (2+4=6),and allocates 4 parts to LinearLayout and 2 for TextView.

Custom Button Class not resizing based on layout_weight android

I have a CircularMeter class which is derived from Button. The problem is that it is not resizing even if the weight given is 0.5 (ie. half the vertical screen).
<LinearLayout
android:id="#+id/WidgetDataLayout"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_alignParentTop="true"
android:layout_weight="0.5"
android:orientation="vertical"
android:layout_gravity="center_horizontal">
<com.test.CircularMeter
android:id="#+id/cm1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal" />
</LinearLayout>
Any Ideas ?
You can take help from this example to make your circularmeter fill half of the vertical screen
eg.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1">
<LinearLayout
android:id="#+id/linearLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_weight="0.5"
android:background="#123456"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#123456"
android:text="#string/hello_world" />
</LinearLayout>
</LinearLayout>
There's no layout_weight in CircularMeter.
It's parent LinearLayout has both android:layout_alignParentTop="true" and android:layout_weight="0.5" which is not correct since layout_alignParentTop is a layout attribute for a RelativeLayout parent while android:layout_weightis an attribute for a LinearLayout parent. The layout XML does not show what is the parent layout actually is. android:layout_height="0dp" would make the layout invisible unless there really is a vertical LinearLayout as a parent.
Also note that layout_weight="0.5" won't make the view size half the screen. After doing first pass layout for a linear layout, the weight mechanism just distributes any remaining space in proportion of element weights. By default an element's weight is 0. So if you have just one element with non-zero weight, it will get all remaining space in its linear layout parent.

layout_weight meaning in the case of nested LinerLayout

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

Fixed proportion of layout on screen

In my app, I have 2 linear layouts: one at the top, one at the bottom.
I'd like that whatever is inside these layout, the layout of the top occupies 60% of the height of the screen and the layout of the bottom 40%.
Here is my XML code:
<?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"
android:layout_weight="1.0" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="vertical"
android:id="#+id/layout_top">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="0.4"
android:id="#+id/layout_bottom">
</LinearLayout>
</LinearLayout>
When these layouts are empty, no problem, they have the good proportion.
The problem is that if I put a small listview in the top layout for e.g. then the layout will take the size of the listview and won't preserve the 60/40% proportion.
I'd like that even if my listview is small (only 3 item for eg), the layout preserve it's 60% and so put some empty space under my listview.
I've tried to change android:layout_height to match_parent but it doesn't change anything.
Try using this Layout it works for me
<?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"
android:layout_weight="1.0" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="6"
android:orientation="vertical"
android:id="#+id/layout_top"
android:background="#FF0000">
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:orientation="vertical"
android:layout_weight="4"
android:id="#+id/layout_bottom"
android:background="#FF00FF">
</LinearLayout>
</LinearLayout>
The trick is to set up a layout_height="0dip" instead of wrap_content in portrait mode and layout_with="0dip" instead of wrap_content in Landscape mode you can use layout-land folder for that.
layout_weight specify extra space in the layoutfot the view. you should try measuring your screen first like:
Display display = ((WindowManager)
getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getHeight();
and then doing some calculation like width*0.6 and 0.4 , this way your layout will always have 60 40 ratio.
Hope This Helps
try layout_height = 0dp in both the children LinearLayouts. Its happening because you have wrap_content which is probably overriding the layout_weight effect.
Simply in your parent layout, replace android:layout_weight="1.0" with android:weightSum="1.0"
This works by setting the weight sum of the parent layout and the weights of the children layouts. The weight of the children should be equal to the weight sum of the parent. Take a look at this http://blog.stylingandroid.com/archives/312

In android layouts what is the effect/meaning of layout_height="0dip"

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.

Categories

Resources