I want to make my TextView vertically scrollable. I have read "Making TextView Scrollable in Android" but since I don't know the size of the screen of the final device, I can't know which value should be set for maximum lines.
Is there any other way, so it gets the scrolling for any screen size?
My XML looks like this:
<?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">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:layout_weight="1.0">
<TextView
android:id="#+id/consola"
android:layout_width="fill_parent"
android:layout_height="match_parent"/>
</ScrollView>
<EditText
android:id="#+id/comando"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.0"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.0">
<Button
android:text="Conectar"
android:id="#+id/boton_conectar"
android:layout_width="wrap_content"
android:layout_weight="0.5"
android:layout_height="wrap_content">
</Button>
<Button
android:text="Enviar"
android:id="#+id/boton_enviar"
android:layout_width="wrap_content"
android:layout_weight="0.5"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
</LinearLayout>
Look, here the structure of my XML layout with scroll:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars="vertical"
android:visibility="visible">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
.....
//your sub-widgets
.....
</LinearLayout>
</ScrollView>
As for me, works fine.
If you do not know number of lines (moreover, it could vary if soft input method are shown or not), you should use RelativeLayout to place you widget like TextView. And then connect both (it's critical, not one but both) top and bottom edges of it to parent withandroid:layout_alignParentTop and android:layout_alignParentBottom attibutes, or neighbors with android:layout_above and android:layout_below attributes.
After both sides are connected to other widgets, android will recalculate size of TextView and scroller properly, even if you change orientation or show/hide soft keyboard.
ScrollView is only allowed to have one sub widget.
You should put the linearlayout inside of the scroll view. and set the textview inside of the linear layout.
Put the TextView inside ScrollView with height = MATCH_PARENT
try:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ScrollView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fillViewport="true"
android:layout_weight="1.0">
<TextView
android:id="#+id/consola"
android:layout_width="fill_parent"
android:layout_height="match_parent"/>
</ScrollView>
<EditText
android:id="#+id/comando"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<Button
android:text="Conectar"
android:id="#+id/boton_conectar"
android:layout_width="wrap_content"
android:layout_weight="0.5"
android:layout_height="wrap_content">
</Button>
<Button
android:text="Enviar"
android:id="#+id/boton_enviar"
android:layout_width="wrap_content"
android:layout_weight="0.5"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
</LinearLayout>
Related
I have an Android layout question. I have a display where I am putting some text into the middle of a view that has a header at the top and three buttons at the bottom. What I am having trouble with is getting the TextView (which is inside a ScrollView) to stretch to fill up the available screen space. If I set the layout_height of the ScrollView to "fill_parent" the three buttons are pushed off the bottom of the screen. If I set it to "wrap_content" it is only as large as is needed to support the text that is put into the TextView.
Here is the XML for the layout I am using:
<?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="fill_parent"
android:orientation="vertical" >
<LinearLayout android:orientation="horizontal"
android:gravity="top"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_launcher">
</ImageView>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
style="#android:style/TextAppearance.Large"
android:text="#string/meetingdetail" />
</LinearLayout>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="#+id/meeting"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
style="#android:style/TextAppearance.Medium" />
</ScrollView>
<Button android:id="#+id/navigation"
android:text="#string/naviation"
android:onClick="meetingInfoOnClick"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button android:id="#+id/mapsingle"
android:text="#string/mapsingle"
android:onClick="meetingInfoOnClick"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button android:id="#+id/goback"
android:text="#string/goback"
android:onClick="meetingInfoOnClick"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Could someone suggest what would work best to make the ScrollView with the TextView fill up the available space but still allow the three buttons to appear?
Set the height of the ScrollView to 0dp and its weight to 1.
<ScrollView
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<TextView android:id="#+id/meeting"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
style="#android:style/TextAppearance.Medium" />
</ScrollView>
However if you don't plan to have more than one views scrollable you should remove the ScrollView and use:
android:scrollbars="vertical"
attribute on your TextView since the TextView is scrollable itself.
Just replace your ScrollView tag code to..
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView android:id="#+id/meeting"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
style="#android:style/TextAppearance.Medium" />
</ScrollView>
It will work fine, if still you have any problem then tell me. if works then accept as answer.
I want the content inside the scrollView as center.
<ScrollView
android:id="#+id/scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="12dp"
android:paddingBottom="20dp"
android:scrollbarStyle="outsideOverlay"
android:layout_gravity="center" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="check"
android:gravity="center_vertical|center_horizontal"/>
</ScrollView>
Note: there is no android:gravity attribute for scrollvew.
any sol:-
I had the same issue and finally figured it out. This is for a vertical ScrollView.
Put your ScrollView inside a RelativeLayout and center it in the RelativeLayout. In order for this to work, your ScrollView should have
android:layout_height="wrap_content"
This is how the final code should look like:
<?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">
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="b1"/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="b2"/>
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="b3"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>
How about this?
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="12dp"
android:paddingBottom="20dp"
android:scrollbarStyle="outsideOverlay" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
android:gravity="center">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="check"
android:gravity="center_vertical|center_horizontal"/>
</LinearLayout>
</ScrollView>
I think a more elegant solution would be to use the ScrollView's android:fillViewport property. A ScrollView is a little different in how it treats it's content view (can only have one), even if you set match_parent (fill_parent) to the ScrollView it won't give that much spacing to it's content view, instead the default behavior is for the ScrollView to wrap the content regardless of what you specify for that view. What android:fillViewport does is tell the ScrollViewto stretch its content to fill the viewport (http://developer.android.com/reference/android/widget/ScrollView.html#attr_android:fillViewport). So in this case, your LinearLayout would be stretched to match the viewport and if the height goes behind the viewport then it will be scrollable which is exactly what you want!
The accepted answer won't work properly when the content extends beyond the ScrollView because it will still center the content view first causing it to cut off a portion of the view, and the ScrollView centered in another layout works but just doesn't feel right, besides I think it will also result in a lint error (useless parent or something along those lines).
Try something like this:
<ScrollView
android:id="#+id/scroller"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="12dp"
android:paddingBottom="20dp"
android:scrollbarStyle="outsideOverlay"
android:fillViewport="true">
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="check" />
</LinearLayout>
</ScrollView>
Just remember that the reason it is being centered here now is because of the android:gravity on the LinearLayout since the ScrollView will stretch the LinearLayout so keep that in mind depending on what you add to the layout.
Another good read on ScrollView although not about centering but about fillViewport is http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/
Use this attribute in ScrollView
android:fillViewport="true"
Example
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
android:fillViewport="true"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--Your Code goes here-->
</RelativeLayout>
</ScrollView>
Make sure to use Single Child in ScrollView just like in above example which is Relativelayout.
For #Patrick_Boss - what stopped the content from cutting of in my application was to change the gravity and layout_gravity to center_horizontal for the LinearLayout.
It worked for me...but not sure if it will work for you.
Modification of #Ghost's answer -
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="12dp"
android:paddingBottom="20dp"
android:scrollbarStyle="outsideOverlay" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="check"
android:gravity="center_vertical|center_horizontal"/>
</LinearLayout>
</ScrollView>
One thing to consider is what NOT to set. Make certain your child controls, especially EditText controls, do not have the RequestFocus property set.
This may be one of the last interpreted properties on the layout and it will override gravity settings on its parents (layout or ScrollView).
using the scroll view inside the ConstraintLayout. It is worked for me
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
Scroll view height should be wrap_content
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
I want something like this:
But I don't know how to resize the TextView so it gets all the available space on screen which is not ocuppied by the EditText or the Buttons. May I do it in the code, or in the xml?
At XML I tried putting the TextView into a FrameLayout, but it makes no difference. Currently looks like:
<?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">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/consola"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scrollbars = "vertical"
android:text="#string/hello"/>
</FrameLayout>
<EditText
android:id="#+id/comando"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:text="Conectar"
android:id="#+id/boton_conectar"
android:layout_width="wrap_content"
android:layout_weight="0.5"
android:layout_height="wrap_content">
</Button>
<Button
android:text="Enviar"
android:id="#+id/boton_enviar"
android:layout_width="wrap_content"
android:layout_weight="0.5"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
</LinearLayout>
At the code I'm just checking if the Buttons are pushed with Listeners. One of them, when pushed, gets the text at the EditText, and appends it to the TextView. It works, and TextView gets higher, while EditText and Buttons downs one line. If I go on appending lines, finaly EditText and Buttons get out of the screen. I want to avoid this behaviour, and accomplish to get this 3 widgets sticked to the bottom of the screen.
Use the android:layout_weight=1 attribute, like the buttons on the bottom of the form. That will assign most of the space to it and anything that's left to the rest of the elements.
It's all about the weight. This should give you what you want:
<?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">
<TextView android:text="TextView"
android:id="#+id/textView1"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp">
</TextView>
<EditText android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<requestFocus></requestFocus>
</EditText>
<LinearLayout android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:text="Button"
android:id="#+id/button1"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_width="0dp">
</Button>
<Button android:text="Button"
android:id="#+id/button2"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1">
</Button>
</LinearLayout>
</LinearLayout>
(Side note: When using weight, setting the corresponding height/width to 0dp sometimes gets around some weird behavior.)
Try android:fillViewport="true".
I want to have a button at the bottom of the listview.
If I use relativeLayout/FrameLayout, it aligns but listView goes down to very botton.
(Behind the button at the bottom)
FrameLayout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentBottom="true">
<Button
android:id="#+id/btnButton"
android:text="Hello"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</FrameLayout>
</FrameLayout>
RelativeLayout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="#+id/btnButton"
android:text="Hello"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</RelativeLayout>
</RelativeLayout>
Above two codes only work like the first image. What I want is second image.
Can anybody help?
Thank you.
A FrameLayouts purpose is to overlay things on top of each other. This is not what you want.
In your RelativeLayout example you set the ListViews height and width to MATCH_PARENT this is going to make it take up the same amount of space as its parent, and thus take up all of the space on the page (and covers the button).
Try something like:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
</LinearLayout>
The layout_weight dictates how the extra space is to be used. The Button does not want to stretch beyond the space it requires, so it has a weight of 0. The ListView wants to take up all of the extra space, so it has a weight of 1.
You could accomplish something similar using a RelativeLayout, but if it is just these two items then I think a LinearLayout is simpler.
<?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="#ffffff"
>
<ListView android:id="#+id/ListView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
</ListView>
<FrameLayout android:id="#+id/FrameLayout01"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="#+id/Button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="button"
android:layout_gravity="center_horizontal">
</Button>
</FrameLayout>
</LinearLayout>
Here is the design you are looking for.
Try it.
I needed two buttons side-by-side at the bottom. I used a horizontal linear layout, but assigning android:layout_height="0dp" and android:layout_weight="0" for the buttons' linear layout didn't work. Assigning android:layout_height="wrap_content" for just the buttons' linear layout did. Here's my working layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/new_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="New" />
<Button
android:id="#+id/suggest_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Suggest" />
</LinearLayout>
</LinearLayout>
RelativeLayout will ignore its children android:layout_width or android:layout_height attributes, if the children have attributes that properly define their left and right or top and bottom values, respectively.
To achieve the result on the right image, showing the list above the button, your layout should look like this:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#android:id/button1"
android:layout_alignParentTop="true"/>
<Button
android:id="#android:id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="#android:string/ok"/>
</RelativeLayout>
The key is to define android:layout_alignParentTop (defines top value) and android:layout_above (defines bottom value) in your RecyclerView. This way, RelativeLayout will ignore android:layout_height="match_parent", and the RecyclerView will be placed above the Button.
Also, make sure you look into android:layout_alignWithParentIfMissing, if you have a more complex layout and you still need to define these values.
I am using Xamarin Android, and my requirement is exactly the same as William T. Mallard, above, i.e. a ListView with 2 side-by-side buttons under it.
The solution is this answer didn't work in Xamarin Studio however - when I set the height of the ListView to "0dp", the ListView simply disappeared.
My working Xamarin Android code is as follows:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="#+id/ListView1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_above="#+id/ButtonsLinearLayout" />
<LinearLayout
android:id="#id/ButtonsLinearLayout"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<Button
android:id="#+id/Button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="#+id/Button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>
I aligned ButtonsLinearLayout to the bottom of the screen, and set the ListView to be above ButtonsLinearLayout.
#jclova one more thing you can do is use layout-below=#+id/listviewid in relative layout
In your relative layout height of listview is match_parent which is fill_parent(for 2.1 and older) so best solution is if you want to use relative layout then first Declare your button then your list view, make list view position as above your button id, If you want button always at bottom then make it alignParentBottom..
Snippet is
<RelativeLayout
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:id="#+id/rl1"><Button
android:layout_width="MATCH_PARENT"
android:layout_height="WRAP_CONTENT"
/><ListView
android:layout_width="MATCH_PARENT"
android:layout_height="0"
android:layout_above="#id/listview"/></RelativeLayout>
This prevents your list view taking whole place and make your button appear..
This will be the best and the most simple solution to the problem. Just add android:layout_above="#id/nameOfId" in the layout that you want to move above with respect to that layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.sumeru.commons.activity.CommonDocumentUploadActivity">
<ListView
android:id="#+id/documentList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/verifyOtp" />
<com.sumeru.commons.helper.CustomButton
android:id="#+id/verifyOtp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="#string/otp_verification" />
</RelativeLayout>
Here's my layout 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">
<TextView android:text="#string/welcome"
android:id="#+id/TextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TextView>
<LinearLayout android:id="#+id/LinearLayout"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="bottom">
<EditText android:id="#+id/EditText"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</EditText>
<Button android:text="#string/label_submit_button"
android:id="#+id/Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
</LinearLayout>
</LinearLayout>
What this looks like is on the left and what I want it to look like is on the right.
The obvious answer is to set the TextView to fill_parent on height, but this causes no room to be left for the button or entry field.
Essentially the issue is that I want the submit button and the text entry to be a fixed height at the bottom and the text view to fill the rest of the space. Similarly, in the horizontal linear layout I want the submit button to wrap its content and for the text entry to fill the rest of the space.
If the first item in a linear layout is told to fill_parent it does exactly that, leaving no room for other items. How do I get an item which is first in a linear layout to fill all space apart from the minimum required by the rest of the items in the layout?
Relative layouts were indeed the answer:
<?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">
<TextView
android:text="#string/welcome"
android:id="#+id/TextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
</TextView>
<RelativeLayout
android:id="#+id/InnerRelativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<Button
android:text="#string/label_submit_button"
android:id="#+id/Button"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>
<EditText
android:id="#+id/EditText"
android:layout_width="fill_parent"
android:layout_toLeftOf="#id/Button"
android:layout_height="wrap_content">
</EditText>
</RelativeLayout>
</RelativeLayout>
The modern way to do this is to have a ConstraintLayout and constrain the bottom of the view to the bottom of the ConstraintLayout with app:layout_constraintBottom_toBottomOf="parent"
The example below creates a FloatingActionButton that will be aligned to the end and the bottom of the screen.
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout>
For reference, I will keep my old answer.
Before the introduction of ConstraintLayout the answer was a relative layout.
If you have a relative layout that fills the whole screen you should be able to use android:layout_alignParentBottom to move the button to the bottom of the screen.
If your views at the bottom are not shown in a relative layout then maybe the layout above it takes all the space. In this case you can put the view, that should be at the bottom, first in your layout file and position the rest of the layout above the views with android:layout_above. This enables the bottom view to take as much space as it needs, and the rest of the layout can fill all the rest of the screen.
In a ScrollView this doesn't work, as the RelativeLayout would then overlap whatever is in the ScrollView at the bottom of the page.
I fixed it using a dynamically stretching FrameLayout :
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fillViewport="true">
<LinearLayout
android:id="#+id/LinearLayout01"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical">
<!-- content goes here -->
<!-- stretching frame layout, using layout_weight -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<!-- content fixated to the bottom of the screen -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- your bottom content -->
</LinearLayout>
</LinearLayout>
</ScrollView>
You can keep your initial linear layout by nesting the relative layout within the linear layout:
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:text="welcome"
android:id="#+id/TextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TextView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:text="submit"
android:id="#+id/Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true">
</Button>
<EditText android:id="#+id/EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/Button"
android:layout_alignParentBottom="true">
</EditText>
</RelativeLayout>
</LinearLayout>
The answer above (by Janusz) is quite correct, but I personnally don't feel 100% confortable with RelativeLayouts, so I prefer to introduce a 'filler', empty TextView, like this:
<!-- filler -->
<TextView android:layout_height="0dip"
android:layout_width="fill_parent"
android:layout_weight="1" />
before the element that should be at the bottom of the screen.
You can do this with a LinearLayout or a ScrollView, too. Sometimes it is easier to implement than a RelativeLayout. The only thing you need to do is to add the following view before the Views you want to align to the bottom of the screen:
<View
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" />
This creates an empty view, filling the empty space and pushing the next views to the bottom of the screen.
1. Use ConstraintLayout in your root Layout
And set app:layout_constraintBottom_toBottomOf="parent" to let the Layout on the bottom of the screen:
<LinearLayout
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent">
</LinearLayout>
2. Use FrameLayout in your root Layout
Just set android:layout_gravity="bottom" in your layout
<LinearLayout
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="horizontal">
</LinearLayout>
3. Use LinearLayout in your root Layout (android:orientation="vertical")
(1) Set a layout android:layout_weight="1" on the top of the your Layout
<TextView
android:id="#+id/TextView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="welcome" />
(2) Set the child LinearLayout for android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom"
The main attribute is ndroid:gravity="bottom", let the child View on the bottom of Layout.
<LinearLayout
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:orientation="horizontal">
</LinearLayout>
4. Use RelativeLayout in the root Layout
And set android:layout_alignParentBottom="true" to let the Layout on the bottom of the screen
<LinearLayout
android:id="#+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
</LinearLayout>
Output
This also works.
<LinearLayout
android:id="#+id/linearLayout4"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_below="#+id/linearLayout3"
android:layout_centerHorizontal="true"
android:orientation="horizontal"
android:gravity="bottom"
android:layout_alignParentBottom="true"
android:layout_marginTop="20dp"
>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
/>
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
/>
</LinearLayout>
Following up on Timores's elegant solution, I have found that the following creates a vertical fill in a vertical LinearLayout and a horizontal fill in a horizontal LinearLayout:
<Space
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
You don't even need to nest the second relative layout inside the first one. Simply use the android:layout_alignParentBottom="true" in the Button and EditText.
If you don't wish to make many changes, then you could just put:
android:layout_weight="1"
for the TextView having ID as #+id/TextView i.e
<TextView android:text="#string/welcome"
android:id="#+id/TextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</TextView>
Creating both header and footer, here is an example:
Layout XML
<RelativeLayout
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:background="#color/backgroundcolor"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="40dp"
android:background="#FF0000">
</RelativeLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="#FFFF00">
</RelativeLayout>
</RelativeLayout>
Screenshot
For a case like this, always use RelativeLayouts. A LinearLayout is not intended for such a usage.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/db1_root"
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:orientation="vertical">
<!-- Place your layout here -->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:orientation="horizontal"
android:paddingLeft="20dp"
android:paddingRight="20dp" >
<Button
android:id="#+id/setup_macroSavebtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Save" />
<Button
android:id="#+id/setup_macroCancelbtn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cancel" />
</LinearLayout>
</RelativeLayout>
Use the below code. Align the button to buttom. It's working.
<?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" >
<Button
android:id="#+id/btn_back"
android:layout_width="100dp"
android:layout_height="80dp"
android:text="Back" />
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.97"
android:gravity="center"
android:text="Payment Page" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit"/>
</LinearLayout>
</LinearLayout>
Use android:layout_alignParentBottom="true" in your <RelativeLayout>.
This will definitely help.
In case you have a hierarchy like this:
<ScrollView>
|-- <RelativeLayout>
|-- <LinearLayout>
First, apply android:fillViewport="true" to the ScrollView and then apply android:layout_alignParentBottom="true" to the LinearLayout.
This worked for me perfectly.
<ScrollView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scrollbars="none"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:id="#+id/linearLayoutHorizontal"
android:layout_alignParentBottom="true">
</LinearLayout>
</RelativeLayout>
</ScrollView>
You can just give your top child view (the TextView #+id/TextView) an attribute:
android:layout_weight="1".
This will force all other elements below it to the bottom.
This can be done with a linear layout too.
Just provide Height = 0dp and weight = 1 to the layout above and the one you want in the bottom. Just write height = wrap content and no weight.
It provides wrap content for the layout (the one that contains your edit text and button) and then the one that has weight occupies the rest of the layout.
I discovered this by accident.
I used the solution Janusz posted, but I added padding to the last View since the top part of my layout was a ScrollView.
The ScrollView will be partly hidden as it grows with content. Using android:paddingBottom on the last View helps show all the content in the ScrollView.