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

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.

Related

Align ImageView to the right with parent layout set to wrap_content

I have a list of items in a horizontal recycler view, and a fairly simple item that should only have a TextView set to wrap_content and an ImageView that should be aligned to the right of the layout.
Theoretically I should be able to just set a layout_weight of 1 on the TextView, but that causes a random space to randomly show up sometimes in the view depending on where it is in the recycler view.
Is there anyway to align the close icon to the right, while still keeping the layout/textview width as wrap_content? The amount of text can vary quite a bit, so I can't actually set a fixed width. I'm fairly certain that I can't just set a layout_gravity of end on the ImageView since the parent layout's set to wrap_content.
See layout attached.
<?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="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/rounded_corners"
android:minWidth="#dimen/min_width"
android:maxWidth="#dimen/max_width"
android:orientation="horizontal">
<WPTextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_weight="1"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|end"/>
</LinearLayout>
With out knowing what the items are supposed to look like and how it needs to behave it is hard to judge what the problem you are having is.
If the image is just supposed to be a small image to the right of the text you could just add a right drawable to the text view:
https://developer.android.com/reference/android/widget/TextView.html#attr_android:drawableRight
If you can replace the LinearLayout by RelativeLayout then you are good to with
<?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="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/rounded_corners"
android:minWidth="#dimen/min_width"
android:maxWidth="#dimen/max_width">
<WPTextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/tv" />
</RelativeLayout>
Spacing between TextView and ImageView can be adjusted with margin on them. The properties used in the above code are self-explanatory.

What am I misunderstanding about aligning views at the bottom?

I tried to align my linearlayout at the bottom of my entire layout which is relative, and found the solution here that does it: How to align views at the bottom of the screen?
But why wouldn't this work also?
<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="com.sandbox.activities.ListActivity">
<ListView
android:id="#+id/my_listview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="#+id/search_footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/my_listview"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<EditText
android:id="#+id/my_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Enter Search Term" />
<Button
android:id="#+id/find_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Find"
android:onClick="findThings"/>
</LinearLayout>
If the listview turns out to be short, like 1 row, "search_footer" is just underneath it, and there is a huge gap below it.
1) "search_footer" is told to align at the bottom of the parent, which is the relativelayout. Since the relativelayout's height is match_parent, and it's the root layout, this means the whole height of the screen, so why wouldn't "search_footer" be at the bottom of the screen no matter the size of the listview?
2) Also, if I change the search_footer's height to match_parent, I expected a really tall button, but it remained unchanged-why?
Add to ListView this attribute
android:layout_above="#id/search_footer"
and remove
android:layout_below="#id/my_listview"
attribute from LinearLayout.
You specified that search_footer align to bottom of parent but also to be below the listview, so in the case that the list is short the search footer just stretches in the space between the listview and the bottom of the screen. you want to specify the footer to be aligned to the bottom of the parent and the listview to be above it:
<ListView
android:id="#+id/my_listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/search_footer"
/>
<LinearLayout
android:id="#+id/search_footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
When you change the height of the search_footer the buttons doe't change because they are set to android:layout_height="wrap_content". Your layout would normally change when you do this however in this case it didn't change either, due to the same reason as above

aChartEngine Plots pushed off top off ScrollView

I've been struggling with this problem for awhile now. Basically, I've created a class that returns me a properly stylized GraphicalView chart; I have one class for bar charts and another for pie charts (I used renderer.setInScroll(true) BTW). I populate my Activity with a few charts and a few TextViews, but the more I add Views (any View) they are pushed off the top of the screen and there is a big empty space at the bottom of the scroll view.
My XML:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/scrollingProfilePaid"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/paidLayoutLinearParent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="00dp"
android:orientation="vertical">
<TextView
android:id="#+id/totalScore"
android:layout_width="wrap_content"
android:layout_height="350dp"
android:layout_gravity="center"
style="#style/GameTextWhite"
/>
<LinearLayout
android:id="#+id/pastScoresChart"
android:layout_width="fill_parent"
android:layout_height="350dp"
android:orientation="vertical"/>
<TextView
android:id="#+id/totalTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="#style/GameTextWhite"
/>
<TextView
android:id="#+id/totalAverageResponseTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="#style/GameTextWhite"
/>
<LinearLayout
android:id="#+id/pastTimesChart"
android:layout_width="fill_parent"
android:layout_height="350dp"
android:orientation="vertical"/>
<!--...........-->
</LinearLayout>
</ScrollView>
What I've tried:
1.ScrollView->android:fillViewport="true"
2.Instead of specifying a height for the charts I set it in the java class using pastScoresChart.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, (int)(dens*350)));
3.Wrapping the ScrollView in a , using a child Relative Layout with android:alignParentTop="true" as the header, another child Relative Layout with android:alignParentBottom="true" as the footer, and changing the ScrollView to android:alignBelow="#id/header". This just made the Scrollview about 40px tall, seemingly making the problem worse.
4.Oodles of other things that I can't recall this second.
I've found a workaround of setting android:marginTop="500dp" (or a similarly large value) in the ScrollView will push the Views back down into their approximate respective positions. Unfortunately it is difficult to get it to fit exactly, and it worries me for device compatibliity. Any suggestions?
The empty space at the bottom of the ScrollView must be because of it's child (LinearLayout) attribute android:layout_gravity="center". Try to use like this:
<LinearLayout
android:id="#+id/paidLayoutLinearParent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
OBS 1: The android:layout_marginTop="00dp" attribute is unnecessary.
OBS 2: fill_parent is deprecated starting from API Level 8 and is replaced by match_parent. So, use match_parent. More on: http://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html
OBS 3: Here is a tip about debugging layouts: change the background color of the views to see what are the bounds of each view.

Elements get hidden in ScrollView

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.

Android: How do I add a footer to a fullscreen scrollview?

I want the footer to be anchored at the bottom of the screen if and only if it can be anchored there without overlapping any other views.
The problem is that I don't know how many views are going to be added to the header or the footer.
If putting the footer at the bottom of the window would make it overlap, I want to put the footer at the bottom of the scrollview. (Maybe by adding it to the RelativeLayout with the rule that it needs to be below the top component?)
Here is a pic of what I'm trying to get:
desired result
Where:
1)The RelativeLayout contains both the TableLayout at the top, and the LinearLayout at the bottom.
2)The TableLayout expands downwards as TableRows get added to it.
3)The LinearLayout expands up from the bottom as views get added to it.
~~~
I'd like for the scrollview to grow in size only enough to fit the components without overlapping.
Thanks in advance for such awesome community support
I think you can solve it in linear layout. You set three blocks in linear layout: header, body, footer. Set body to fill_parent and layout_weight=1, this way body will expand to fill what left after header and footer taken its part from parent. Whole structure place into ScrollView.
<?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:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow><TextView android:text="Text1"/></TableRow>
<TableRow><TextView android:text="Text2"/></TableRow>
</TableLayout>
<RelativeLayout
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:text="#string/lorem_ipsum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:text="Text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:text="Text4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</ScrollView>
I tested this in Emulator of Android 2.1 and it looks it works.

Categories

Resources