Android layout with view fixed to bottom - android

I'm trying to create a layout in Andorid. I need a TextView (2 in diagram below) fixed to the bottom of the screen. With content (1 in diagram) comprising of scrollview and editTexts.
The problem I have is when the soft keyboard comes up (3 in diagram), the red box marked 2 also comes up, above the keyboard. I would like the red box to remain offscreen and the entire content to scroll in the space remaining above the soft keyboard.
I've tried putting the red box (2) in the LinearLayout but it never fixes itself to the bottom, there's always a small gap at the bottom of the screen. I've also tried changing android:windowSoftInputMode in the manifest but this isn't the desired affect.
This is what I have:
<?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">
<ScrollView
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:isScrollContainer="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText />
<EditText />
</LinearLayout>
</ScrollView>
<TextView
android:id="#+id/3"
android:layout_alignParentBottom="true"
text="3" />
</RelativeLayout>
Any suggestions would be very much appreciated.

All you need to do is switch your activity's windowSoftInputMode flag to "adjustPan". Check the official documentation for more info.
<activity
...
android:windowSoftInputMode="adjustPan">
</activity>

Try using the below layout see if this is what you are looking for..
<?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">
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:isScrollContainer="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<EditText
android:layout_width="80dp"
android:layout_height="40dp"
android:id="#+id/ed1"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:layout_marginBottom="50dp"/>
<EditText
android:layout_width="80dp"
android:layout_height="40dp"
android:id="#+id/ed2"
android:layout_gravity="center_horizontal"
android:layout_marginTop="50dp"
android:layout_marginBottom="50dp"/>
</LinearLayout>
</ScrollView>
<TextView
android:id="#+id/btext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="this is 3rd view"
android:layout_marginBottom="20dp"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
TL;DR version, i just removed two lines in your scrollview code:
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
with
android:layout_centerInParent="true"
See if that helps!
And any reason why you are using both android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" on scrollview?

Here's one idea that works.
Adjust the layout so that the red box (2) is inside the LinearLayout
Create a small view between the red box and the last EditText
Give the red box and the LinearLayout an id, so we can manage them from the java class.
Your xml should look like this:
<?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">
<ScrollView
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true"
android:isScrollContainer="false">
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText />
<EditText />
<View
android:id="#+id/stretcher"
android:layout_width="match_parent"
android:layout_height="0dp" />
<TextView
android:id="#+id/2"
android:layout_gravity="bottom"
text="2" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
Now in your java onActivityCreated add this code:
final View mainLayout = getView();
final View mainContent = getView().findViewById(R.id.content);
final View stretcherView = getView().findViewById(R.id.stretcher);
//Main layout uses weight some, so we can't hard code the size of the circles.
//We must dynamically re-size
mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (android.os.Build.VERSION.SDK_INT >= 16) {
mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
//Calculate the desired height of the stretcher view to be the remainder between full screen and content.
int stretchHeight = mainLayout.getHeight() - mainContent.getHeight();
//Apply calculated height remainder to stretched view.
//This enables our bottom box to be pushed to the bottom without obstructing the content when the keyboard appears.
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) stretcherView.getLayoutParams();
params.height = stretchHeight;
stretcherView.setLayoutParams(params);
}
});
The view listener measures the height of the full view then subtracts the height of the content. This leaves us with the gap between the content and the bottom of the screen. Using the stretcher view we can now push the red box down to the bottom of the page, just as if it was alignParentBottom.
When the keyboard appears, the red box is inside the scroll.

Related

Android: How to put an EditText that's in a ScrollView above another view when focused?

My app design makes me having this kind of layout for every form view: a floating button at the bottom of the view. I'm using ConstraintLayout to set dynamically the height of the button with always the same left/right margin no matter the screen width, and so I end up having this layout:
<ConstraintLayout>
<ScrollView>
<EditText/>
<EditText/>
<!-- ... -->
<ConstraintLayout /> (1)
</ScrollView>
<Button/>
</ConstraintLayout>
(1) A clear view with the height of the bottom button in order not to hide the views at the bottom in the scroll view that would be hidden by the button
Basically, that's what it looks like:
Now the problem I encounter is when I tap an edit text at the bottom, for example here the 4th one:
The edit text moves up the keyboard, but not the floating button, and it often comes to be hidden by it. I know that I have to do something in the edit text's onFocusChanged() method, but I don't know what...
I know that I have to do something in the edit text's onFocusChanged()
method.
No. You don't have to do things manually. Simply add this attribute to the button. This will make the button positioned on the bottom of the parent layout rather that on the bottom of the EditText (You can skip this if are already doing it).
app:layout_constraintBottom_toBottomOf="parent"
And add this attribute to the activity tag which represent that specific activity. It will reduce the height of the viewable area by an amount which is equal to the height of the soft keyboard in such a way that it won't go behind the content.
android:windowSoftInputMode="adjustResize"
See the doc for more detailed explanation.
Also note that a ScrollView can host only one direct child as in the below example.
<ScrollView
...>
<LinearLayout
...>
<!-- You can place multiple views here -->
</LinearLayout>
</ScrollView>
1- you can move your edit text to top of the scrollView when they focus changed to true :
here is code :
java Code :
LinearLayout containerOfScrollViewViews= findViewById(R.id.containerOfScrollViewViews);
for (int i = 0; i < containerOfScrollViewViews.getChildCount(); i++) {
containerOfScrollViewViews.getChildAt(i).setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
int[] xy = new int[2];
v.getLocationInWindow(xy);
if (hasFocus) ((ScrollView)findViewById(R.id.scrollView))
.smoothScrollBy(xy[0], xy[1]);
}
});
}
My XML :
<?xml version="1.0" encoding="UTF-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
app:layout_constraintTop_toBottomOf="parent"
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="#id/btn">
<LinearLayout
android:id="#+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:hint="A"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="B"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="C"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="D"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="E"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="F"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="H"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="J"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="K"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
<EditText
android:hint="Z"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp" />
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="add"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
2 - or your can attach your button to bottom of the scroll view so when keyboard appears than scrollView and button both goes above the scrollView
3- you can listen to keyboard visibility Chang and hide/show your button
here is link for this solution :
SoftKeyboard open and close listener in an activity in Android?
AndroidManifest.xml add android:windowSoftInputMode="adjustPan|stateHidden"in your activity ;
Or, setKeyboardListener, changed your scrollview position
Use releative Layout and put in scrollview android:layout_above="floating button"
this should solve overlaping or hiding by that button.
also softinput adjust pan
Scoll view should contain only one view
so put all edit text inside a linear or any layout inside scroll view
<android.support.constraint.ConstraintLayout>
<ScrollView .........>
<LinearLayout..........>
<EditText ....... **//Add EditText around 6 to 7**
..............
.............. />
</LinearLayout>
</ScrollView>
<RelativeLayout **// Fix the button in bottom gravity.**
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="bottom">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Bottom Gravity" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
And please set androidmanifest.xml file
<activity
android:windowSoftInputMode="adjustPan"/>
I've solve this problem hope so it will help you.

Change the position of a text in android studio

I just started a programing in course in android studio using Java and XML and cant really figure out how to do a simple task. I have 3 buttons at the top of the screen, they fill up the whole width of the screen. I want to add a text below these 3 buttons, but i dont really now how to specify this. Right now i have:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_main">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_textcolor" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_textsize" />
<TextView
android:text="South Africa"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
/>
</LinearLayout>
Now, the text in the text element is displayed at the right side of the screen, its barely visible. The text gets cramped up so tight that it gets misaligned verticaly. What would i do if i instead wanted the text inside the textview element to be displayed just below the 3 buttons, to the left horizontaly, like normal text?
Thank you!
Use something like this. Inside the TextView tag add:
android:layout_below="#+id/buttonid"
Obviously you have to use relative layout for using this
Here you go
<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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_main">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/button_send" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/button_textcolor" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/button_textsize" />
</LinearLayout>
<TextView
android:text="South Africa"
android:layout_height="match_parent"
android:layout_width="wrap_content"
/>
</LinearLayout>
Use RelativeLayout instead of LinearLayout. There are also many other layouts you can try. Check here for the other type of available layouts.
RelativeLayout lets child views specify their position relative to the
parent view or to each other (specified by ID). So you can align two
elements by right border, or make one below another, centered in the
screen, centered left, and so on. By default, all child views are
drawn at the top-left of the layout, so you must define the position
of each view using the various layout properties available from
RelativeLayout.LayoutParams.

ScrollView not sizing itself correctly

I'm trying to get a ScrollView to take up as much screen space as it needs until it would start pushing items below (outside) it off the screen, then it needs to stop expanding and become scrolly.
<?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"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff0000"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable"
/>
<!--
android:text="just one line"
-->
</ScrollView>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Button"
/>
</LinearLayout>
As it is above the ScrollView fills the entire screen height and pushes the button off the bottom of the screen.
If I add android:layout_weight="1" to the ScrollView then it works for this case - the button is at the bottom and the ScrollView stops above it - but when the ScrollView doesn't have much content (replace the text with the one-liner) then the ScrollView doesn't shrink to fit around the content so is far too tall.
I've tried using RelativeLayout with no success - if the Button is android:layout_below the ScrollView then the ScrollView will push it off the bottom of the screen if it has a lot of content.
Here's what I want it to look like: in the first image the ScrollView has a lot of content and so expands to fill the available height but doesn't push the items below it (the button) offscreen, in the second image the ScrollView doesn't have much content so takes up just the height it needs allowing the items below it (the button) to move up the screen:
What you can do, is to correct the height in your code. It's a bit hacky and I would like to see another solution, but off the top of my head I do not know anything better.
What you would need is to add a OnGlobalLayoutListener and calculate within it the minimum of either the ScrollView height or the height of the container surrounding your ScrollView minus the height of your Button.
Then set the size with setLayoutParams() on your ScrollView.
And you have to remove the listener to avoid an endless loop :-)
final View scrollview = findViewById(R.id.scrollview);
final View container = findViewById(R.id.container);
final View button = findViewById(R.id.button);
scrollview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int height = scrollview.getHeight();
int heightButton = button.getHeight();
int heightContainer = container.getHeight();
int min = Math.min(heightContainer - heightButton, height);
int width = scrollview.getWidth();
Log.v("test", "min: " + min);
scrollview.setLayoutParams(new RelativeLayout.LayoutParams(width, min));
// do not forget to remove the listener
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
scrollview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
else {
scrollview.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
For this to work you have to use wrap_content as the height of the ScrollView in your layout file. And the outer container has to be a RelativeLayout so that the Buttonis rendered and has a non-zero height!
If you use paddings or margins you would have to consider those values in the computation.
Try this:
<?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"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/button"
android:background="#ff0000">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable" />
<TextView
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable" />
<TextView
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable" />
<TextView
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable" />
<TextView
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable" />
<TextView
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable" />
<TextView
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable" />
<TextView
android:padding="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="taking\nup\lots\nof\nlines\nto\nmake\nthe\nscrollview"s\ncontent\ntaller\nthan\nthe\nspace\navailable\nto\nit\nwhich\nshould\nmake\nthe\nscrollview\nstop\nabove\nthe\nbutton\nand\nbecome\nscrollable" />
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Button" />
</RelativeLayout>
Just try adding fillViewport = "true" on your scroll view

View over another View

I have some Popups on my screen, and need something not so common.
I Layout my popup with Header + Content + Footer into a LinearLayout. But I need a little arrow to show on my component.
When the popup is above the anchor and the arrow is down, I use the following code to have it drawed.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/content" android:orientation="vertical"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<LinearLayout android:id="#+id/header" android:background="#drawable/background_header"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
<HorizontalScrollView android:background="#drawable/background"
android:layout_width="wrap_content" android:layout_height="match_parent"
android:scrollbars="none">
</HorizontalScrollView>
<ImageView android:id="#+id/arrow_down" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_marginTop="-3dip"
android:src="#drawable/quickcontact_arrow_down" />
</LinearLayout>
In runtime I'm able to place the arrow exactly above the anchor with the following code.
ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) mArrowDown
.getLayoutParams();
param.leftMargin = root.getMeasuredWidth()
- (screenWidth - anchor.getLeft());
And it's show correctly.
Now I need do the same thing but the arrow needs to show in the up side.
My problem is that the arrow need overlap a little over the other View (cause the backgrounds color match them), so this is why it's need to be draw after.
I tried with a FrameLayout and letting "content" has some topMargin, but it's not working.
I know it's can be done with AbsoluteLayout, but I'm avoiding it at all costs.
EDIT:
Following Josh answer, I wrote the following code.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content">
<LinearLayout android:id="#+id/content"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:fadingEdgeLength="0dip">
<RelativeLayout android:id="#+id/header"
android:background="#drawable/background_header" android:orientation="horizontal"
android:layout_width="match_parent" android:layout_height="wrap_content">
</RelativeLayout>
<HorizontalScrollView android:background="#drawable/background"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:scrollbars="none">
</HorizontalScrollView>
</LinearLayout>
<ImageView android:id="#+id/arrow_up" android:layout_above="#id/content"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:src="#drawable/quickcontact_arrow_up" />
</RelativeLayout>
But I don't know why, the arrow is not show now.
I won't pretend to have read all that xml. I think what you want is RelativeLayout, though. You should be able to use this technique to place any little arrow view where ever you like, relative to the bounds of the RelativeLayout which encompasses it.
If you wrap everything you have in a single RelativeLayout, for instance, and then add, say, a Button as the second item, you can give the button attributes like alignParentRight=true and layout_marginRight=10dp to place the button 10dp from the right edge of the screen, ON TOP of whatever views are already there.

Adding view to bottom of layout inside a scrollview

So my layout looks basically like this:
<ScrollView>
<RelativeLayout>
<BunchOfViews/>
<ImageView android:layout_alignParentBottom="true"/>
</RelativeLayout>
</ScrollView>
I have the ScrollView so all of the layout always is visible no matter the height of the screen. The problem is that on a very high screen, I still want my ImageView to be at the bottom. However, a child of a ScrollView don't seem to have a defined bottom. The View is placed at the top of the layout. How can I solve this problem in a neat way?
I ran into the same issue. I never could find a very pleasing solution, but here is how I did it. Maybe someone else has a better way, I hate adding layouts that don't do anything.
My hack was to add a dummy linearlayout at the bottom of the scrollview that has fill_parent to take up all the room and force the scrollview to fill the screen. Then add whatever component I want to that linearlayout.
Here is one of my layouts that does this:
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:fillViewport="true" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="15px" >
<!-- bunch of components here -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/spinner"
android:layout_marginTop="5px"
android:gravity="center_horizontal|bottom"
android:paddingTop="2px" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="20px"
android:paddingRight="20px"
android:text="Delete" />
</LinearLayout>
</RelativeLayout>
</ScrollView>
I had the same issue and found this page:
http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/
Basically, you set the ScrollView's android:fillViewport to true, which will allow the child view to expand to the same height as the ScrollView itself, filling out the space. You then just need to have one of the child controls' layout_height set to fill_parent and layout_weight to 1, causing that control to "spring" to fill the empty space.
Note that if the contents of the ScrollView are already tall enough to fill the ScrollView, the android:fillViewport has no effect, so the setting only kicks in when needed.
My final XML looks like similar to this:
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_height="wrap_content">
<LinearLayout
android:layout_height="fill_parent"
android:layout_weight="1">
<!-- this expands to fill the empty space if needed -->
</LinearLayout>
<!-- this sits at the bottom of the ScrollView,
getting pushed out of view if the ScrollView's
content is tall enough -->
<ImageView
android:layout_height="wrap_content"
android:src="#drawable/footer_image">
</ImageView>
</LinearLayout>
</ScrollView>
it seems that the linearlayout isn't necessary, all that is important is the fillViewPort.
you could just use
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottomParent="true">
now that you have specified the relativelayout to be at least the size of the screen.
its work for me perfectly android:fillViewport="true"
Joel Malone's answer Adding view to bottom of layout inside a scrollview does that trick. My solution is almost the same, except that I use Space widget to do the work of filling the rest height inside the parent layout. Like this:
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
>
<LinearLayout
android:orientation="vertical"
android:layout_height="wrap_content"
>
<android.support.v4.widget.Space
android:layout_height="match_parent"
android:layout_weight="1"
/>
<ImageView
android:layout_height="wrap_content"
android:src="#drawable/footer_image"
/>
</LinearLayout>
</ScrollView>
Attention:
fill_parent in the other answers is noted as deprecated for a long time;
Compare to an empty LinearLayout to fill the rest of parent layout, I think Space is much more appropriate(it's designed to do that job.)
Finally, don't forget that important attribute at the beginning of ScrollView: android:fillViewport="true". They together make this trick.
just put this attribute android:fillViewport="true" to your ScrolView
and you will got what you need
On your view that you want to be at the bottom use android:gravity="bottom"
From: http://code.google.com/p/k9mail/source/browse/k9mail/trunk/res/layout/account_setup_basics.xml?r=1314
This should help you:
<RelativeLayout
android:layout_marginTop="-45dip"
android:padding="0dip"
android:layout_alignParentBottom="true"
android:gravity="bottom|right"
android:background="#android:drawable/bottom_bar"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
<Button
android:id="#+id/manual_setup"
android:text="#string/account_setup_basics_manual_setup_action"
android:minWidth="#dimen/button_minWidth"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginBottom="-4dip"
android:layout_alignParentLeft="true"
android:layout_centerVertical="false"
/>
<Button
android:id="#+id/next"
android:text="#string/next_action"
android:minWidth="#dimen/button_minWidth"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:drawableRight="#drawable/button_indicator_next"
android:layout_marginBottom="-4dip"
android:layout_alignParentRight="true"
android:layout_centerVertical="false"
/>
</RelativeLayout>
ScrollView view = new ScrollView( this );
ScrollView.LayoutParams lps = new FrameLayout.LayoutParams( FILL_PARENT, FILL_PARENT, Gravity.CENTER );
LinearLayout layout = new LinearLayout( this );
// what ever you want in the Layout
view.addView( layout, lps );
I tried alot to align the Scroll View to bottom of the screen but thats not possible according to this link.
https://newbedev.com/how-do-i-align-views-at-the-bottom-of-the-screen
The way i found was to create a view with 1dp height and aa id (lets say android:id="#+id/bottomView") at the bottom of your XML page.
now just add these attributes to your scroll view..
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:fillViewport="true"
android:layout_alignBottom="#+id/bottomView"
>
Here is how you can use a ConstraintLayout to align the image view at the bottom:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/content_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Text 1"
app:layout_constraintBottom_toTopOf="#+id/space_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
<Space
android:id="#+id/space_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#+id/image_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/text_view" />
<ImageView
android:id="#+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="..."
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/space_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

Categories

Resources