I'm currently modifying an xml layout, and I want to group all of the views into 2 sections, each half of the height available. The layout looks something like this:
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
...Lots of stuff...
</LinearLayout>
What I've done is to wrap each "half" of the views in a linear layout, and assign a weight to each.
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- Top half -->
<LinearLayout
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="fill_parent"
android:orientation="vertical">
... stuff and things ...
</LinearLayout>
<!-- Bottom half -->
<LinearLayout
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="fill_parent"
android:orientation="vertical">
... things and stuff ...
</LinearLayout>
</LinearLayout>
I can't figure out why this doesn't give me 2 equal panes. The lower one seems to take up 90% of the available space. I've tried adding (android:weightSum="2") to the container layout, but to no avail. None of these layouts have IDs, so the code behind shouldn't be able to modify them. Any idea what is going on here? Are the child views able to modify their "half" containers so that they wouldn't appear equal?
This link may be of some use to you:
http://www.chess-ix.com/blog/the-use-of-layout_weight-with-android-layouts/
What you are doing seem to be correct, but probably the content in your Linearlayouts may be the culprit.
Trying adding a weightSum to the parent LinearLayout, like so:
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="2">
<!-- Top half -->
<LinearLayout
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="match_parent"
android:orientation="vertical">
... stuff and things ...
</LinearLayout>
<!-- Bottom half -->
<LinearLayout
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="match_parent"
android:orientation="vertical">
... things and stuff ...
</LinearLayout>
</LinearLayout>
Also, I change layout_height of the children: you won't need fill_parent for the child LinearLayouts since the parent has that property already.
Related
I'm struggling on a layout management so I decided to ask here.
I would like to get 3 layouts working in a certain way.
I have 3 views vertically dispatched into a RelativeLayout (let's call them VTop, VMiddle and VBottom).
VBottom is a Button, I want him to stay aligned with the bottom of the screen and to never move or get resized (actually working).
VMiddle is a scroll view. I want this ScrollView to take all possible place between the bottom button (VBottom) and the top most layout (VTop) but never having it height inferior to an specific size.
I would like to have VTop (A linear layout containing some TextViews and other stuffs) wrapping all of its content as long as VMiddle doesn't get smaller that its minimum size.
Actually the code I have is almost working but when I Inflate too much content into VMiddle, it keeps growing towards the top of the screen and VTop completely disappear. I want VMiddle to stay at it minimum size if VTop doesn't have enough space to wrap his content.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayout1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linearLayout1" <!-- VTop -->
android:layout_above="#+id/eventDetail_RateLayout"
android:layout_alignParentTop="true"
android:layout_margin="10sp"> <!-- LOT OF VIEWS, NEED TO BE WRAPPED AS MUCH AS POSSIBLE -->
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100px"
android:id="#+id/eventDetail_RateLayout" <!-- Not visible for now, you can ignore it -->
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:minWidth="25px"
android:minHeight="25px"
android:background="#color/common_google_signin_btn_text_light_default"
android:layout_above="#+id/eventDetail_CommentScrollView"
android:visibility="gone" />
<ScrollView
android:id="#+id/eventDetail_CommentScrollView" <!-- VMiddle -->
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/eventDetail_commentButton">
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/eventDetail_CommentLayout" />
</ScrollView>
<Button
android:text="commenter"
android:id="#+id/eventDetail_commentButton" <!-- VMiddle, this one is doing ok -->
android:background="#666"
android:textColor="#f8f8f8"
android:layout_width="match_parent"
android:layout_height="30sp"
android:layout_alignParentBottom="true" />
</RelativeLayout>
Thanks for your answers.
Try the following code for the ScrollView -
<ScrollView
android:id="#+id/eventDetail_CommentScrollView" <!-- VMiddle -->
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_below="#id/linearLayout1"
android:layout_weight="1"
android:layout_above="#+id/eventDetail_commentButton">
...
</ScrollView>
Use this, however the kind of UI you want can be easily achieved using Linear layout and using weight and weightSum properties.. also rename ID of the layout and views accordingly
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/topLayout"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentTop="true"
android:background="#70AD47"
android:orientation="vertical">
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/btnBottom"
android:layout_below="#+id/topLayout"
android:background="#ED7D31"
android:minHeight="400dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/btnBottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#4472C4"
android:text="Bottom button" />
</RelativeLayout>
1. Add attribute android:layout_below="#id/linearLayout1" and android:layout_above="#id/eventDetail_commentButton" to ScrollView to keep it at middle position.
2. Use ScrollView and its child LinearLayout height android:layout_width="match_parent" although its not necessary.
No matter how big the top and bottom layout, middle scrollview will always fill the middle free spaces. It will never change the height of top and bottom layout.
Here is the working layout:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/relativeLayout1">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/linearLayout1"
android:layout_alignParentTop="true"
android:layout_margin="10sp">
</LinearLayout>
<Button
android:text="commenter"
android:id="#+id/eventDetail_commentButton"
android:background="#666"
android:textColor="#f8f8f8"
android:layout_width="match_parent"
android:layout_height="30sp"
android:layout_alignParentBottom="true" />
<ScrollView
android:id="#+id/eventDetail_CommentScrollView"
android:background="#4D4A58"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/linearLayout1"
android:layout_above="#id/eventDetail_commentButton">
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/eventDetail_CommentLayout" />
</ScrollView>
</RelativeLayout>
Hope this will help~
Use android:layout_below="#+id/linearlayout1"
in eventDetail_RateLayout
I'm pretty sure none of the given answers achieve what you're looking for. What you wanna do is not simple because it involves a circular dependency: you basically want your vTop view to wrap and fill any space left by your vMiddle view (android:layout_above="#id/vMiddle") and at the same time you want your vMiddle view to wrap and fill any space left by your vTop view (android:layout_below="#id/vTop").
The only solution I can imagine would be to check and set the view sizes programmatically, I don't think this is doable only by rearranging your layout.
I finally achieved to get something close to what I wanted. I combined layout_above and below and fixed the size of VTop by making the Huge TextView scrollable. I have now VTop and VBottom at a fixed size and VMiddle taking the rest of the place at the center.
Thanks for your fast answers :)
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've decided to use 2 RelativeLayouts for my app, one Layout for one portion of child Views on the screen to the left, the other for child Views to go to the right.
The problem is I don't know how to lay them out in XML so that the middle white space isn't included when I inflate my Layout.
This is what I want.
When I use 1 RelativeLayout, the middle white space is filled with the RelativeLayout, and I can't touch anything behind it.
Thank you very much for reading.
Do something similar to the following example.
This will create a LinearLayout with 2 RelativeLayouts using layout_weight to space the RelativeLayouts and then you can populate the RelativeLayouts with whatever you want.
The Buttons are just place holders for the example.
<?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="horizontal" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TEST1" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TEST2" />
</RelativeLayout>
</LinearLayout>
I separated the interface of my app in three areas: header, content and footer.
The header has a fixed size (it has only one image), while the footer and content have sizes that can vary.
In devices with higher resolutions I thought to insert the header and footer on the screen, and reserve any free space for the content area.
In devices with low resolutions thought of putting the content length as little as possible (something like wrap_content) and insert the footer below (requiring the user to perform scroll to view the footer).
The best I got was using RelativeView:
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentTop="true" >
(...)
</LinearLayout>
<LinearLayout
android:id="#+id/footer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true" >
(...)
</LinearLayout>
<FrameLayout
android:id="#+id/content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/footer"
android:layout_below="#+id/header"
android:lay >
(...)
</FrameLayout>
</RelativeLayout>
For resolutions larger works as expected, the problem is that for small resolutions: the content is less than it should, because it takes the space between the header and footer.
How can I solve the problem?
I could not find another way to get content assuming all the free space of the screen (in large resolutions), because I can not simply use fill_parent, since the content is between the header and footer.
I also tried using min-height, but without success.
Top level RelativeLayout layout_height make that fill_parent.
Then FrameLayout remove the layout_above property, just saying it's below the header should be enough.
Finally, FrameLayout may be causing the problem as it's normally used when only 1 element is on the screen and it fills the screen. Try replacing this with a LinearLayout. I've done something exactly like what you want in one of my apps, the layout is (keep in mind in my case I swap out the FrameLayouts for Fragments which are LinearLayout or RelativeLayout based.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainBack"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/transparent" >
<FrameLayout
android:id="#+id/headerFrag"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/homeAdMsgFrag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
<ListView
android:id="#+id/contactList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/homeAdMsgFrag"
android:layout_alignParentLeft="true"
android:layout_below="#id/headerFrag"
android:background="#color/transparent"
android:cacheColorHint="#color/transparent" >
</ListView>
</RelativeLayout>
Some days before I also faced this issue, to solved what I did that I created Header.xml and footer.xml and included this two xml in my all others activities xmls because this two are common in all others activities.
To meet global resolution issue, I used weightsum and weight, applying weight will fixed your header and footer area and content area too.
This way I done in my one of project to resolve this issue, just try it, hope it will works for you.
EXAMPLE
<LinearLayout
android:weightSum="10"
android:orientation="vertical"
android:id="#+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_weight="2"
android:layout_height="0dp"
android:orientation="vertical" >
(...)
</LinearLayout>
<FrameLayout
android:id="#+id/content"
android:layout_width="fill_parent"
android:layout_weight="6"
android:layout_height="0dp">
(...)
</FrameLayout>
<LinearLayout
android:id="#+id/footer"
android:layout_width="fill_parent"
android:layout_weight="2"
android:layout_height="0dp"
android:orientation="vertical" >
(...)
</LinearLayout>
</LinearLayout>
Thanks.
I am trying to keep the ScrollView from taking too much space at the bottom of the screen as it keeps my two buttons from showing. I also don't want to manually set a height for the ScrollView.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
...
android:orientation="horizontal">
<Button .../>
<TextView .../>
<Button .../>
</LinearLayout>
<ScrollView
android:layout_width="math_parent"
android:layout_height="wrap_content">
<ImageView .../>
<ImageView .../>
<ImageView .../>
</ScrollView>
<LinearLayout
...
android:orientation="horizontal">
<Button .../>
<Button .../>
</LinearLayout>
</LinearLayout>
This is a generalized version of my layout. What is happening is that the ScrollView extends all the way to the bottom of the screen no matter how many items are in it. This causes the two buttons at the bottom of the screen to not be visible.
How can I stop this from happening without manually setting a height for the ScrollView?
I've used android:layout_height="wrap_content" for all my views.
Isn't this supposed to automatically distribute the height of the views to fit the screen's height?
(Wanted to include images, but my rep isn't high enough yet (-_-))
The way I would resolve this today is by using RelativeLayout as a base. Anchor the two LinearLayout's to the top and bottom of the RelLayout respectively. Then I would insert the ScrollView but I would make sure to set it's layout properties as follows:
android:layout_below="topLinearLayout"
android:layout_above="bottomLinearLayout"
Have you tried using layout_weight for the ScrollView. IIRC, if a non-zero weight is set for ONE element (and the corresponding dimension set to 0dp) then it'll fill up the remaining space in that dimension, after setting out the measurements for sibling views (in this case, the LinearLayout on top and bottom of the ScrollView.
Apologies, not got an Android environment to check and it's been a while.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout>
...
Something at the top
...
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
**android:layout_height="0dp"
android:layout_weight="1"**>
<ImageView .../>
<ImageView .../>
<ImageView .../>
</ScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
...
buttons
...
</LinearLayout>
</LinearLayout>
Here's an answer with more information about the layout_weight attribute.