50

I've got a ViewPager and an ActionBar with tabs. One of these tabs has a ListView and when I tap on one of the options in that ListView, I add a child Fragment which is the detail view for that row.

That detail view is a ScrollView with a LinearLayout inside it. The ScrollView is match_parent/match_parent and the LinearLayout inside it is width=match_parent and height=wrap_content. On a phone-sized emulator, the detail view fills the screen as desired, but on a tablet, the detail view only covers part of the width of the screen... even though the width of the ScrollView and the width of the LinearLayout are both match_parent.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/rootView" style="@style/RootScrollView">

    <LinearLayout android:id="@+id/scrollContentView" style="@style/ScrollViewContent">
        ...
    </LinearLayout>
</ScrollView>

Here is the style for the scroll view:

<style name="RootScrollView">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">match_parent</item>
</style>

Here is the style for the content LinearLayout:

<style name="ScrollViewContent">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:paddingLeft">15dp</item>
    <item name="android:paddingRight">15dp</item>
    <item name="android:orientation">vertical</item>
    <item name="android:background">@drawable/image_legal_paper_tile</item>
</style>

The content view has a repeated background image_legal_paper_tile which is this:

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/legal_paper_tile" 
    android:gravity="fill_horizontal"
    android:tileMode="repeat" />

So, the image should stretch horizontally and repeat which creates a yellow legal paper pad in the background.

This is what the list and the detail view look like the phone emulator:

enter image description here

This is what the list and detail view look like on a real tablet. The yellow legal pad fragment SHOULD be filling the entire width of the screen, but it's not.

enter image description here

EDIT:

Here is the background legal paper image:

enter image description here

It's 320px wide. The phone emulator is 480px wide and the image stretches, correctly, to fill the width of the screen. It then repeats vertically as intended. However, it's not stretching to fill the width of the screen on the tablet.

The width shown on the tablet is NOT the native size of the image, because it changes size based on the content. When the fragment first loads, it is one width. Then I fill in the fields and execute the calculation which adds some text at the bottom of the content view. That text is wider than the existing content and so when the text is set the width of the fragment increases to support the wider content.

So, in short, no, the width on the tablet is not the native size of the image. The image IS stretching, just not stretching all the way.

Kenny Wyland
  • 20,844
  • 26
  • 117
  • 229
  • Are using only one layout for all layout sizes? How big is your background image? Is the background image size what is seen on the tablet? Then it can be a tile repeat issue (for that maybe check this [link](http://stackoverflow.com/questions/4077487/background-image-not-repeating-in-android-layout)). – abbath Mar 17 '13 at 21:20
  • The width shown on the tablet is NOT the native size of the image, because it changes size based on the content. When the fragment first loads, it is one width. Then I fill in the fields and execute the calculation which adds some text at the bottom of the content view. That text is wider than the existing content and so when the text is set the width of the fragment increases to support the wider content. – Kenny Wyland Mar 18 '13 at 05:06
  • if you used layout margin in linear layout of scroll's child you should change it to padding to work true. – Azade Rahmati Dec 07 '16 at 08:15

6 Answers6

202

On the ScrollView use android:fillViewport="true" and for child of ScrollView android:height="wrap_content". If you would like to have many child's with different attributes make a main child as container. Set it as wrap_content and its child as match_parent .

example :

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:fillViewport="true">

    <LinearLayout
        android:id="@+id/dynamic_frame"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <LinearLayout
            android:id="@+id/dimrix_sub_child"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:visibility="gone" >
        </LinearLayout>

        <LinearLayout
             android:id="@+id/dimrix_sub_child_21"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:visibility="gone" >
        </LinearLayout>
    </LinearLayout>
</ScrollView>

In this example I can set visibility in the code for each child and it will match parent as you wish .

ppreetikaa
  • 1,149
  • 2
  • 15
  • 22
Jesus Dimrix
  • 4,378
  • 4
  • 28
  • 62
  • 2
    This worked really well for me. Do you have any explanation for WHY this works, I would love to know. Thanks! – Shooky Nov 15 '18 at 17:14
19

Try adding android:fillViewport="true"to your ScrollView

remember that android:layout_height=”fill_parent” means “set the height to the height of the parent.” This is obviously not what you want when using a ScrollView. After all, the ScrollView would become useless if its content was always as tall as itself. To work around this, you need to use the ScrollView attribute called android:fillViewport. When set to true, this attribute causes the scroll view’s child to expand to the height of the ScrollView if needed. When the child is taller than the ScrollView, the attribute has no effect.

Pankaj Talaviya
  • 3,328
  • 28
  • 31
4

I had a similar problem and solved it this way :

    scrollView.setFillViewport(true);
ucMedia
  • 4,105
  • 4
  • 38
  • 46
0

I've figured out a workaround, but I won't accept this answer and hopefully someone will find the real answer.

In my list view fragment, the onListItemClick() handler, I set a couple of properties (minWidth and minHeight) on the detail fragment. Then in the onCreateView() method of the detail fragment, I set the minimum width and height to that value.

The detail fragment then properly fills the space and still allows scrolling, etc.

Kenny Wyland
  • 20,844
  • 26
  • 117
  • 229
0

If your parentView is a ConstraintLayout just set android:layout_height="0dp" to a parentView of ScrollView, like this:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout>

  <SomeView/>

  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="0dp" 
    android:orientation="vertical">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <YourItens>

        </LinearLayout>

    </ScrollView>

  </LinearLayout>

  <SomeView .../>

</androidx.constraintlayout.widget.ConstraintLayout>
Daniel Beltrami
  • 756
  • 9
  • 22
0

To set internal layout of scrollview match parent you use this in XML

android:fillViewport="true"

your HorizontalScrollView looks like

<HorizontalScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fillViewport="true"
                >
Adnan Bashir
  • 645
  • 4
  • 8