24

I need to have a LinearLayout inside a SrollView and that LinearLayout must have a margin from the ScrollView. At first, the only way I could think of to solve that issue was having a LinearLayout inside another LinearLayout with the margins set on the this last layout. They wouldn't work if they were set in the outer LinearLayout.

Example:

<?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:orientation="vertical"
    android:fillViewport="true"
    android:background="@color/layout_color_green">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@color/layout_color_yellow">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="10dp"
            android:orientation="vertical"
            android:background="@color/layout_color_blue">
        </LinearLayout>
    </LinearLayout>
</ScrollView>

enter image description here

My question is: Why do I need to do this?

If I had only one LinearLayout there would be no margins...

Example:

<?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:orientation="vertical"
    android:fillViewport="true"
    android:background="@color/layout_color_green">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:orientation="vertical"
        android:background="@color/layout_color_blue">
    </LinearLayout>
</ScrollView>

enter image description here

Then, searching for some similar issue, I found a few layouts which gave me the idea of using padding in the ScrollView instead of margin in the LinearLayout. This also solves my problem and I don't need a LinearLayout inside another one. It's a more elegant solution.

Still, I would like to understand why the simple margin inside the LinearLayout doesn't work when inside a ScrollView. Because it does work fine if it's not inside a ScrollView.

Anyone knows why?

rfgamaral
  • 16,546
  • 57
  • 163
  • 275

2 Answers2

16

I digged a little bit into the source code:

ScrollView extends FrameLayout. This one has some margin issues itself and ScrollView is not even trying to solve that. The margins are basically ignored while measuaring.

But in the end it doesn't matter since you should be able to define a padding on the ScrollView itself (it's an affirmation, didn't try that). There should be no need for margin for a single child view.

Knickedi
  • 8,742
  • 3
  • 43
  • 45
  • 1
    But the thing is that the margins are not the only problem. If I have the `LinearLayout` height set to `wrap_content` and all children height set to `match_parent`, the children will in fact be `fill_parent`, which is the value that comes from the `ScrollView`. And not `wrap_content` which is the value from the `LinearLayout`, their direct parent. This problem also doesn't happen if I use one `LinearLayout` inside another. So I guess there's more to the `ScrollView` than we know!? – rfgamaral Sep 24 '11 at 15:50
  • Yes of course. You forced that behavior with `android:fillViewport="true"`. – Knickedi Sep 24 '11 at 15:54
  • So, do you recommend I go with the padding instead of the margin and set all children of the `LinearLayout` to `wrap_content`? – rfgamaral Sep 24 '11 at 15:57
  • I can't recommend padding since this is the only choice ;-)`android:fillViewport="false"` will **not** force the `LinearLayout` to be `fill_parent`, that's it. So it shouldn't be streched and so the children wouldn't neither. – Knickedi Sep 24 '11 at 16:02
  • I'm not sure what to do because this is part of a bigger problem where I have a `GridView` inside a `LinearLayout` which is inside a `ScrollView`. And after searching and reading a lot, I just found out I'm not supposed to have a `GridView` inside a `ScrollView`. I have no idea how to do my UI now... :( – rfgamaral Sep 24 '11 at 16:05
  • Ok, I will stop after this comment since this is not the initial question anymore. But I will answer that anyway: That's the same reason why you shouldn't use a `ListView` in a `ScrollView`. 1. They can't ever be `wrap_content` in height. 2. They are already scrollable, it makes no sense to place them in a `ScrollView` which is also vertically scrollable. – Knickedi Sep 24 '11 at 16:12
  • It really is the only way to add margins inside the scrollview, its really anoing you have to hack it like this. – Warpzit Dec 12 '11 at 12:51
  • The only problem is, adding padding to the ScrollView will make the scollbar stick out from the edge of the screen, and will also look ugly as the content will appear to scroll past the top and bottom into nowhere. Hard to explain via text. Try it for yourself to see. – aaronsnoswell Jul 18 '12 at 13:45
12

Hello Knickedi and Ricardo Amaral,

Though this answer is marked as solved but I want to put some lights on the issue.

As Knickedi said, ScrollView extends FrameLayout.

So My answer is that You can set the layout_gravity of LinearLayout within scrollView and then layout_margin will work in LinearLayout as case with linearLayout within FrameLayout.

I had same issue and I've applied this and it worked for me. :)

Example :

<ScrollView
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">

                <LinearLayout
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="top"
                    android:layout_marginTop="30dp"
                    android:orientation="vertical" >
</ScrollView>
Prabs
  • 4,923
  • 6
  • 38
  • 59
hims_3009
  • 1,737
  • 14
  • 23