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
Related
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.
I am new to Android programming and I would like to make a table/grid (generically speaking, not sure the best layout to use just yet). I want the table to fill the entire screen, but I want to have variable sized height and width for cells. For example I would like column one to be 1/3 of the display width, and column 2 to be 2/3 of the display width. Similarly, I would like some cells to be 1/4 of the screen height, and others to be 1/2 of the screen height, etc. What is the best layout to use for this? I am looking at GridLayout, LinearLayout, and TableLayout.
Tx!
You can do it easily using LinearLayout.
Set its layout_weight at 1.
Then, set the layout_weight of your first element at 0.3 and the layout_weight of your second at 0.66. Then it will give to your first element 1/3 or the screen and the rest to your second one.
Put for each element a width of 0dp. Then according to the weight your gave to your elements, your elements will spread on the screen.
Hope it helps.
There are two approaches to this:
1) If you know what all your items will be and can pre-define them.
I would use LinearLayouts inside LinearLayouts (parent orientation set to vertical, children set to horizontal). Then use weight_sum on the parent (e.g. 3) and layout_weight on the children (e.g. 2, 1). Set the children layout_width to 0dp.
2) If you are trying to represent a variable list of data
This is a little more complicated, but you might be best off using a RecyclerView with a GridLayoutManager which will allow you to programmatically set the span of the items based on type.
Edit:
Example of #1:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4">
<TextView
android:layout_width="0dp"
android:layout_weight="3"
android:layout_height="wrap_content"
android:background="#abc"/>
<TextView
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:background="#cda"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4">
<TextView
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:background="#af0"/>
<TextView
android:layout_width="0dp"
android:layout_weight="2"
android:layout_height="wrap_content"
android:background="#ffa"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="4">
<TextView
android:layout_width="0dp"
android:layout_weight="4"
android:layout_height="wrap_content"
android:background="#f00"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
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.
I want to have a relative layout inside another full-screen relative layout, occupying full width but 50% of its parent's height, preferably done with XML and not java code.
I have figured out how how to align parent's center, and how to fill up the width, but is there a way to get 50% of parent's height? What about 30%? 6.2834%?
<?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">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="??????????"
android:layout_centerInParent="true" >
The reason I'm trying to do percentage is that, if I specify it with "dip", while the object will remain the same size, the layout will look a lot different on different screen sizes (e.g. a phone and a tablet).
EDIT:
Thank you for all the answers about using LinearLayout and weighting. I have looked at that before, too. I feel I might have over-simplified the problem. Say I need something like this:
I suppose I could use complicated LinearLayout and weighting to outline the center square, then having the center square to fill_parent, like so:
But then what should I do with the other 3 squares (layouts)? Can I have another "layer" of LinearLayout for another square? Or should I divide up the whole screen into many, many small cells and having these sublayouts span over multiple cells (not sure if this is even possible)?
Try to use LinearLayout with weightSum
<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:weightSum="2"
android:gravity="center_vertical"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#FF0000">
</RelativeLayout>
</LinearLayout>
If you don't absolutely need it nested in one RelativeLayout you can use weight in a LinearLayout as others have pointed out. I just added in an additional RelativeLayout above and below so you can use the rest of the screen if you are trying to. If not, just remove the other RelativeLayouts.
<?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:id="#+id/ParentLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10" >
<RelativeLayout
android:id="#+id/RelativeLayoutTop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:background="#color/torange" >
</RelativeLayout>
<RelativeLayout
android:id="#+id/RelativeLayoutMid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="5"
android:background="#color/tpurple"
android:padding="8dp" >
<TextView
android:id="#+id/description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/describe"
android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/RelativeLayoutBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:background="#color/torange" >
</RelativeLayout>
I usually go with a LinearLayout for this and set the weight to a certain percentage :
<?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">
<View
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="25"/>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="50">
</RelativeLayout>
<View
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="25"/>
</LinearLayout>
To your edit:
At some point you need to determine the layout. Start by taking the layout in groups. Look for patterns. In your simple explanation we have devised a way using a linearlayout to group 3 objects with one in the middle. With your new layout, could you group those items in any way?
Once you have simple layout patterns set, maybe add specific spacing that you are looking for by defining weights. Then you might want to add a relative layout and start anchoring views to specific views. Ask yourself do they overlap? Does one view always position on top of other views or on the sides. What defines the bounds of your views and then take it from there using linear layouts, weights, relative layouts, toLeftOf, toRightOf, bellow, above, margins, and padding.
Here is an example of what I mean by grouping like objects. It's by no means the best solutions but that all depends on how you define the positioning parameters.
Yellow = vertical linear layout
Green = horizontal linear layouts
You have 1 large vertical layout and inside two horizontal layouts with multiple objects inside of that. From there you can break it down into easier to manage portions on how to arrange and item within that layout. Now with relative layouts you could position items relative to another object, you could remove some of the work handled by the linear layouts but you will then be defining their distance relative to the other objects and might have to fiddle to get the layout to adjust properly on different screen sizes (reason to not use static positioning).
Maybe try using a LinearLayout with 3 layouts inside with android:layout_weight set to 1, 2, 1.
<?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" >
<RelativeLayout
android:background="#FF0000"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dip" >
</RelativeLayout>
<RelativeLayout
android:background="#00FF00"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dip" >
</RelativeLayout>
<RelativeLayout
android:background="#FF0000"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dip" >
</RelativeLayout>
</LinearLayout>
RelativeLayout does not support percentage of width and height for children. Use LinearLayout with android:layout_weight attribute.
I would like to create a layout that has two LinearLayout(vertcal position).
First linearLayout has 80% from space and the other 20% (I used weightSum=10).
On second layout I have a textinput and when keyboard appears the screen size is reduced so the second linearlayout wich has 20% is too small.
I would like that my secondLayout to have minimum 100dp and the first layout to have the rest but I don't know how to implement this.
Thank you !
The weight is used to distribute the remaining empty space or take away space when the total sum is larger than the LinearLayout. Set your widths to 0dip instead and it will work.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum:"10" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="8" >
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="2">
</LinearLayout>
</LinearLayout>