Problems with RelativeLayout - android

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.

Related

Trying to size correctly android layouts

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 :)

How to set layout height to one screen height except actionbar and status bar, in scrollview

I have a layout in a scrollview and I add another layout to the end of the first one. Actually I am trying to make a one page design and the rest of the other views will appear after scrolling. I tried to put linearlayout1 and linearlayout2 to another view but it didn't work. Also I set scrollview android:fillViewport="true" but it made the scrollview in screen size.
I've added an image of what I want, but it could also be one view, I mean lin1 and lin2 together.
I can set width and height for one phone but I want to do this for each screen. For example like yahoo weather app. They have done one layout for first view and start another view from the end of screen. I tried so many things but I couldn't imagine how to put layouts. Could you help me?
Thanks for your help
Here is what I want
Here is I tried:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scroller"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/linearlayout1"
android:background="#android:color/holo_purple"
android:layout_width="match_parent"
android:layout_height="350dp" >
<TextView
android:text="LinearLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="#+id/linearlayout2"
android:background="#android:color/holo_blue_bright"
android:layout_width="match_parent"
android:layout_height="250dp"
android:orientation="vertical">
<TextView
android:text="LinearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:background="#android:color/holo_green_light"
android:layout_width="match_parent"
android:layout_height="350dp">
<TextView
android:text="LnearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</ScrollView>
But unfortunately I couldn't configure this for each screen size.
enter image description here
Just try this.
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/action_bar"
Instead of hardcoding the height as in:
android:layout_height="250dp"
Set android:layout_height="0dp" and use
android:layout_weight="25"
And also in the other layout use weight. Weight works like this, if you have 3 components in your container, set the weights to let's say 1, 2 and 3 => they will take in that order 1/6, 2/6 and 3/6 of the container. 6 being the sum of 1,2,3. So here instead of using heights as 350 and 250, you can set them to 0 and use weights 2.5 and 3.5 or 25 and 35.

Custom view shrinking: previously occupied space is not cleared

In a custom view, OnMeasure and OnSizeChanged is used to set the instrisic size and get the final size respectively.
In OnDraw, a drawable is drawn using the current Width/Height.
Now if the view is told to change its intrisic size, it will requestLayout. This triggers OnMeasure/OnSizeChanged and finally OnDraw.
It works fine, the drawable is always displayed using the correct inner size.
The problem is, if the new inner size is smaller than the old one, android leaves the old drawing (which seems to be "under" the new one, but in fact should have been cleared by android).
I tryed to clear the view content inside OnDraw, but the drawing rectangle is alread clipped to the new view size.
It sounds like a bug in LinearLayout not clearing its content when a child's view size shrink. Testing on Android 4.4 / Samsung S3 4G / CyanogenMod cm-11-20151004-NIGHTLY.
Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/content"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:padding="8dp">
<LinearLayout
android:orientation="horizontal"
android:id="#+id/content"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:gravity="top">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#CCD39F">
<MyCustomView
android:id="#+id/myview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
What i see after updating the custom view size. Only the "black part" should be displayed, not the white one.
It should be something like this instead:
I found the problem and a workaround.
The real problem is in LinearLayout. From Android 4.0.3 to Android 6. When this vertical linearlayout has weight=1 and height=0dp, and it has only one child which height is smaller than the available height. The first time this child is drawn, no problem. If the height of this child shrink, the area below it is not repainted. So it stays with the old content of the first child, instead of being refilled with the layout background color.
In the following layout code, i demonstrate the problem and solution. The solution is to add a second child which will take the rest of the free space below the first child. Using this technics it works as expected when the first child shrinks, the second one expands and the newly "empty" space is repainted correctly.
So it is really a bug in LinearLayout.
<?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"
android:background="#000000">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="top">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#CCD39F">
<MyCustomView
android:id="#+id/icon"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- Solution. To see the problem, remove the following layout -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#111111" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right">
<Button
android:text="Other demo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btnNextImage" />
<Button
android:text="Next SVG"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btnGoEmpty" />
</LinearLayout>
</LinearLayout>

Scrollview fill_parent with "layout_weight"

I'm having problems when putting android:layout_width="fill_parent" Because spaces eats and grows all the greater .
When I have in wrap_content , it works fine , but when I turn , I have half the blank screen.
Is there any way to fix it?
My scroll (with rows static, not dinamically):
<ScrollView
android:id="#+id/scrollView19"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:fillViewport="true">
My row
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center">
My space into scroll
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.1">
I'm trying to test all cases of scrollviews for Android ( Google ) has no deficiencies.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="Match_parent"
android:layout_weight="0.7"
android:gravity="center">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1.3">
Do try with the weights,may be it would work for you....
I solved create a new layout-land,, it seems the developers thought about how to go creating layouts, I tried to give the same layout (resizable for all views that exist), now in the same layout (portrait-horitzontal) does not work, maybe in the future can do not create a layout-land.

Android: Layout height in percentage of screen resolution

I'm quite new in Android, so it'll probably be a stupid question, but here it goes.
I have a RelativeLayout of Activity. In this layout I have another Layout at bottom of a screen. Sometimes I hide it or make it visible, this matters not. Is it possible to make the another layout's height lets say 27% of total screen height? The idea is to keep the other content, except this layout on screen.
Have anyone tried something like this?
LinearLayout can handle this via android:layout_weight. For example, here is a layout containing three Button widgets, taking up 50%, 30%, and 20% of the height, respectively:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="50"
android:text="#string/fifty_percent"/>
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="30"
android:text="#string/thirty_percent"/>
<Button
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="20"
android:text="#string/twenty_percent"/>
</LinearLayout>
However, you cannot simply declare that an arbitrary widget at an arbitrary point in your layout file should take up an arbitrary percentage of the screen size. You are welcome to perform that calculation in Java and adjust your widget's LayoutParams as necessary, though.
you can try this, is more complexe but useful.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/parent_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name" />
<LinearLayout
android:id="#+id/parent_of_bottom_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true" >
<LinearLayout
android:id="#+id/content_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="27">
//Add your content here
</LinearLayout>
</LinearLayout>

Categories

Resources