Elements get hidden in ScrollView - android

I have the following:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/layout_question_types"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="18sp"
android:layout_marginTop="18sp"
android:orientation="horizontal" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- some content -->
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginRight="18sp"
android:gravity="right"
android:orientation="vertical" >
<!-- some more content -->
</RelativeLayout>
</LinearLayout>
</ScrollView>
However, when I turn the phone horizontal to force the scrollbar, the scrollbar appears but the content at the bottom of the screen gets hidden.
Any ideas? There are similar questions on SO but they don't seem to fix the problem. Thanks.

Reason of this are margins and ScrollView parent FrameLayout which has some margin problems. Margins are ignored in measuring and scroll view measure its size without these margins and that is why the bottom part of inner views in ScrollView is not visible.
You can solve it simple wrapping child LinearLayout with another LinearLayout without margins.

Related

LinearLayout is getting cut off inside ScrollView Android

I have an activity in my app where I would like the user to be able to vertically scroll the content contained inside a LinearLayout which in turn is inside a ScrollView. Here is a summary of what the layout XML for this activity looks like:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="20dip"
android:orientation="vertical">
<!-- a bunch of standard widgets, omitted for brevity -->
<!-- everything renders but starting in this TextView -->
<!-- content begins to get truncated -->
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:gravity="left"
android:textSize="20dip"/>
<!-- this View, really just a trick for a horizontal row, is -->
<!-- completely cutoff -->
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="#color/green" />
</LinearLayout>
</ScrollView>
</LinearLayout>
What I am observing is that content in the inner LinearLayout is being cutoff inside the ScrollView. In the final TextView above, when it contains little text, then the View below it does render in portrait, but does not in landscape. When this TextView contains a lot of text, then it gets cutoff in portrait mode.
I tried the recommendations I found on Stack Overflow. Adding bottom padding to the ScrollView did not resolve the problem, nor did swapping the ScrollView for a NestedScrollView.
Any helpful suggestions would be welcome. This is actually turning out to be a blocker.
Change your inner LinearLayout's margin to padding. Or, if you really need it to be margin (maybe you're using a custom background), wrap your LinearLayout in a FrameLayout.
The ScrollView is taking its height (or, more accurately, it is computing its scrollable range) from the LinearLayout. This value doesn't include margins, so your ScrollView is going to be "too short" by the sum of the LinearLayout's top and bottom margins.
The margins are ignored while measuring, See this
So you can provide padding to your ScrollView and remove margins from your LinearLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- a bunch of standard widgets, omitted for brevity -->
<!-- everything renders but starting in this TextView -->
<!-- content begins to get truncated -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="20dp"
android:gravity="left"
android:textSize="20dip"/>
<!-- this View, really just a trick for a horizontal row, is -->
<!-- completely cutoff -->
<View
android:layout_width="match_parent"
android:layout_height="2dip"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:background="#color/green" />
</LinearLayout>
</ScrollView>
Also fill_parent is deprecated and renamed match_parent in API Level 8 and higher

Android Scrollview Won't fill parent space

I have a relative layout fills the entire screen. I want to add a scrollview in the middle of it to wrap a bunch of content so that I can make it pan up when the soft keyboard gets displayed. However, as soon as I wrap it in a scrollview, the bottom most layout stops filling the remainder of the screen.
Here is the XML where I have the ScrollView commented out.
<include
android:id="#+id/top_bar_with_save_button"
layout="#layout/top_bar_with_save_button"/>
<FrameLayout
android:id="#+id/log_entry_title_frame"
android:layout_below="#id/top_bar_with_save_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/log_entry_title_frame"
android:layout_alignParentBottom="true">
<!--
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/log_entry_title_frame"
android:orientation="vertical"
android:background="#f00">
<!-- Lots of stuff in here -->
<EditText
android:id="#+id/log_entry_notes"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:gravity="top|left"/>
</RelativeLayout>
<!--
</ScrollView>
-->
</LinearLayout>
It looks like this:
But as soon as I remove the comment from the ScrollView it immediately compresses like this:
Why does this happen? I need it to fill the entire space on the screen, and I cannot figure out what is happening. Can anyone tell me how to fix this? Thanks!
You need to add the fillViewport="true" attribute to your ScrollView tag. Or you can add it programmatically with scrollView.setFillViewPort(true);. Otherwise, the ScrollView will wrap to its child's content height.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
... >
layout_height of scrolling container should be "wrap_content".

ScrollView white space at bottom

I'm having an issue with ScrollView which leaves a blank space at the bottom. It is filled with few TextViews and GridViews and should fill the whole RelativeLayout parent.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".showPictures">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView.../>
<GridView.../>
...
</LinearLayout>
</ScrollView>
</RelativeLayout>
Does anybody have an idea what's wrong?
Make your relative layout height match parent, also use android:fillViewPort = "true" in your scroll view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".showPictures">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
//...
you can use this code to avoid extra padding on bottom of scroll view:
android:overScrollMode="never"
In my case I had a GridView inside a ScrollView that was causing this issue. It turns out the the layout_gravity in the GridLayout as 'center' was causing this issue.
'center_horizontal' makes more sense for a ScrollView anyway, but I added the ScrollView after the original layout was done (using 'center'), when I saw that the elements were going off-screen on some devices, hence the issue.
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" // having this as android:layout_gravity="center" causes extra space at bottom!
android:columnCount="2">
....
Give weight to every child in the scroll view including linear layout with value 1

How to Prevent Scrolling within FrameLayouts and Instead Have the Parent LinearLayout Handle all Scrolling?

I have a scrollable LinearLayout parent with a few FrameLayouts nested inside it as follows:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="vertical"
android:orientation="vertical">
<FrameLayout
android:id="#+id/hb_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/gn_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/yt_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
I would like FrameLayouts to take up the space they need, allowing for scrolling of the full view through the LinearLayout.
Issue is: the LinearLayout will only take up the screen, it won't scroll, instead the FrameLayout's will scroll if the content overflows the bottom of the screen.
To be clear, I just want the FrameLayouts to fill whatever space they need, and the LinearLayout can scroll it like one long view. Must I fix the FrameLayout heights to achieve this? If so, is there risk of my layout breaking on different screen sizes/densities (or does DP really work in all cases?).
Thank you immensely!
EDIT: I have confirmed that setting fixed heights in the FrameLayout does exactly what I want this to do: scroll as one. However, why doesn't wrap_content measure the height and then go from there? That is what I expected the case was... I'm not certain how to judge the right heights for each element.
Try adding a scrollview to the layout
<?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="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical">
<FrameLayout
android:id="#+id/hb_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/gn_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/yt_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>

ScrollView not scrolling to the end of inner LinearLayout's bottom margin

I'm having issues with a Fragment consisting of a ScrollView containing a LinearLayout. I'm trying to create an effect where the LinearLayout has a white background and looks like a piece of paper scrolling on a coloured background. The way that I'm trying to achieve this is by having the ScrollView occupy the full space of the fragment and then the LinearLayout inside has android:layout_margin="16dp" to create the space around the "paper".
This way, the scroll bar of the ScrollView appears in the coloured background area, the margin at the top scrolls away along with the content and the margin at the bottom only scrolls in when one reaches the end.
Unfortunately in this configuration the ScrollView won't scroll all the way to the end and in fact cuts off a very small amount of the text at the bottom. I suspect that the ScrollView isn't taking into account its child's margins in its vertical scrolling distance. To solve this I've wrapped the LinearLayout in a FrameLayout which solves the issue, but seems superfluous. Any pointers on how to eliminate this unneeded container would be appreciated.
Note: setting android:padding="16dp" on the ScrollView and scrapping the margins doesn't have the desired effect, as then the padding appears on all four edges continuously, regardless of scroll position.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
tools:context=".ArticleFragment" >
<!-- This FrameLayout exists purely to force the outer ScrollView to respect
the margins of the LinearLayout -->
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:layout_margin="16dp"
android:background="#color/page_background" >
<TextView
android:id="#+id/article_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textIsSelectable="true" />
<TextView
android:id="#+id/article_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true" />
</LinearLayout>
</FrameLayout>
</ScrollView>
I remember having trouble with the ScrollView somehow not making it to the end of it's contents when the content layout had a top margin. I solved the problem with a little hack, adding an empty view to the end of the LinearLayout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".ArticleFragment" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:layout_margin="16dp" >
<TextView
android:id="#+id/article_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textIsSelectable="true"
android:background="#color/page_background" />
<TextView
android:id="#+id/article_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:background="#color/page_background" />
<!-- Add a little space to the end -->
<View
android:layout_width="fill_parent"
android:layout_height="30dp" />
</LinearLayout>
</ScrollView>
I used a similar empty view also in the beginning of the LinearLayout to avoid top/bottom margins completely.
EDIT: I just realised that you also wanted the end of the "paper" to show up when reaching the end of the view. In that case you might want to set the background color to the TextViews instead of the layout itself. Then make sure there's no margin between the title and the article (use padding as separation).
EDIT2: I should learn to check when the questions were asked... Well, maybe this still helps someone. :)
The question is old, but I've had issues with ScrollView being ill-behaved when wrapping FrameLayout. It also doesn't seem to consider the margins of contained layouts. You could replace the FrameLayout with another single-child LinearLayout, which should measure correctly. I would've removed the FrameLayout completely and simply added summed margin with padding on the inner layout:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="26dp"
android:background="#color/page_background" >
<!--...-->
I'd get rid of the FrameLayout and make the LinearLayout the child of the ScrollView with match_parent set as the layout height. If that still doesn't work, consider replacing the bottom margin with another arbitrary View with the desired height and background as the last item in the LinearLayout.

Categories

Resources