108

I want the content inside the scrollView as center.

<ScrollView
    android:id="@+id/scroller"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingTop="12dp"
    android:paddingBottom="20dp"
    android:scrollbarStyle="outsideOverlay"
    android:layout_gravity="center" >

    <Button 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:text="check" 
        android:gravity="center_vertical|center_horizontal"/>

</ScrollView>

Note: there is no android:gravity attribute for scrollvew.

any sol:-

hadi
  • 3,046
  • 1
  • 19
  • 11
Padma Kumar
  • 19,893
  • 17
  • 73
  • 130

7 Answers7

184

I had the same issue and finally figured it out. This is for a vertical ScrollView.

Put your ScrollView inside a RelativeLayout and center it in the RelativeLayout. In order for this to work, your ScrollView should have

android:layout_height="wrap_content"

This is how the final code should look like:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:layout_centerVertical="true" >

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

            <Button
                android:id="@+id/button1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="b1"/>
            <Button
                android:id="@+id/button2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="b2"/>
            <Button
                android:id="@+id/button3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="b3"/>
        </LinearLayout>

    </ScrollView>

</RelativeLayout>
Sphinx
  • 394
  • 3
  • 17
hadi
  • 3,046
  • 1
  • 19
  • 11
  • 30
    This one seems to work better for me than the accepted answer. Thank you! – Patrick Boos Oct 31 '13 at 14:38
  • Ideally android should look into this issues when there is a hierarchy of layout. Also should provide both scrolling(horizontal/vertical) options in one scrollview.BTW thanks @hadi – mayank_droid Jan 05 '15 at 09:42
  • 2
    This is a bit of a hack, so while this works fine it _feels_ wrong. – DariusL Aug 12 '15 at 13:48
  • This is ok if you dont need your ScrollView to fill the viewport for some reason. Otherwise its fine – Darko Petkovski Oct 13 '15 at 16:15
  • 3
    Hey its working, but doesn't scroll when the keyboard is visible, I tried add in manifest `android:windowSoftInputMode="stateHidden|adjustResize"` but, dont scroll, help me please – Helio Soares Junior Apr 15 '16 at 17:41
  • I had problems with the view clipping with the accepted answer. This method worked for me instead. I don't know why it behaves like that though, seems like a bug. – Jim Oct 17 '17 at 19:24
  • 3
    No need to use heavy `RelativeLayout` as root view. It can be `FrameLayout` and `android:layout_gravity="center_vertical"` for `ScrollView` – Pavlo28 Sep 08 '18 at 11:58
148

How about this?

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingTop="12dp"
    android:paddingBottom="20dp"
    android:scrollbarStyle="outsideOverlay" >


    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" 
        android:layout_gravity="center"
        android:gravity="center">

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="check" 
            android:gravity="center_vertical|center_horizontal"/>
    </LinearLayout>

</ScrollView>
Ghost
  • 3,966
  • 1
  • 25
  • 36
  • 2
    Yeah! How ABOUT that! This worked fantastically for me, so thank you very much, kind sir. – RileyE Jan 10 '13 at 21:12
  • 103
    There is one problem with this. If you content in the ScrollView is bigger than the scrollview, it will still center it and cut off content at the top (not sure yet why though). Meaning you can't scroll there. – Patrick Boos Oct 31 '13 at 13:39
  • 7
    PatrickBoos is right; this doesn't seem to work. Use hadi's answer below, vertically centering the scrollview in a RelativeLayout. – Mason Lee Nov 03 '13 at 12:13
  • Yes, this way have bug, content bigger than scrollView, the content will not scroll to top, his top is negative number, strange :( – krosshj Aug 15 '17 at 06:57
103

I think a more elegant solution would be to use the ScrollView's android:fillViewport property. A ScrollView is a little different in how it treats it's content view (can only have one), even if you set match_parent (fill_parent) to the ScrollView it won't give that much spacing to it's content view, instead the default behavior is for the ScrollView to wrap the content regardless of what you specify for that view. What android:fillViewport does is tell the ScrollViewto stretch its content to fill the viewport (http://developer.android.com/reference/android/widget/ScrollView.html#attr_android:fillViewport). So in this case, your LinearLayout would be stretched to match the viewport and if the height goes behind the viewport then it will be scrollable which is exactly what you want!

The accepted answer won't work properly when the content extends beyond the ScrollView because it will still center the content view first causing it to cut off a portion of the view, and the ScrollView centered in another layout works but just doesn't feel right, besides I think it will also result in a lint error (useless parent or something along those lines).

Try something like this:

<ScrollView
    android:id="@+id/scroller"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingTop="12dp"
    android:paddingBottom="20dp"
    android:scrollbarStyle="outsideOverlay"
    android:fillViewport="true">

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

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="check" />

    </LinearLayout>

</ScrollView>

Just remember that the reason it is being centered here now is because of the android:gravity on the LinearLayout since the ScrollView will stretch the LinearLayout so keep that in mind depending on what you add to the layout.

Another good read on ScrollView although not about centering but about fillViewport is http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/

Vasily Kabunov
  • 6,511
  • 13
  • 49
  • 53
Brian Ethier
  • 1,031
  • 1
  • 7
  • 3
  • 11
    This looks like the most correct implementation, no extra views required. – DariusL Aug 12 '15 at 13:49
  • 1
    Nice solution, seems to be the cleanest one for me. Thanks for it – Benjamin Scharbau Sep 18 '16 at 11:42
  • 2
    Works better than the accepted answer, you saved me a lot of time! Really well done Brian Ethier! – Mattia Ruggiero Dec 20 '16 at 17:04
  • This is the correct solution, for all the reason described in it.. If you try the solution above, and your scroll view is wider than your screen, you will indeed have part of your scrollview unreachable and be unable to scroll to it... This should be accepted as the proper solution – Speckpgh Apr 01 '18 at 04:36
  • 2
    Typical Stackoverflow .. the correct solution is often somewhere in the middle. – Teovald Jul 11 '18 at 02:04
  • Stack overflow should have option to promote correct implementation, other than Vote. This shouldn't be on bottom. – Mahendran Oct 17 '18 at 07:31
18

Use this attribute in ScrollView

android:fillViewport="true"

Example

 <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbarStyle="outsideOverlay"
android:fillViewport="true"
>
   <RelativeLayout
              android:layout_width="match_parent"
              android:layout_height="wrap_content">

         <!--Your Code goes here-->

   </RelativeLayout>

</ScrollView>

Make sure to use Single Child in ScrollView just like in above example which is Relativelayout.

Abhishek Garg
  • 3,092
  • 26
  • 30
  • @JoshuaKing may because it is 7 years old question and i posted this answer recently 9 months ago. – Abhishek Garg Feb 07 '19 at 09:45
  • Ha! oh.. truth. Well, it worked perfectly! So thanks! – Joshua King Feb 07 '19 at 22:31
  • 1
    This should definitely be the accepted answer! It works perfectly and centers a ScrollView if the content is less than the container size. Works for both ScrollView and HorizontalScrollView. Thank you so much! – Ray Li Apr 16 '19 at 21:08
  • this can have the unintended effect of stretching your content inside the scroll view – martinseal1987 Dec 20 '19 at 13:11
  • @martinseal1987 i think effect will depends on your child component, that how you make your layout design, though if this does not work for you, you can make your own custom scroll view component as per your design and work needs. and please also share you desired result screenshot with me, so i can look into and can provide your more better and working solution. ready to help. cheers. – Abhishek Garg Dec 21 '19 at 14:39
  • LIKE i'd rather use this pram it so helped – Mostafa Imani May 06 '22 at 10:33
9

For @Patrick_Boss - what stopped the content from cutting of in my application was to change the gravity and layout_gravity to center_horizontal for the LinearLayout.

It worked for me...but not sure if it will work for you.

Modification of @Ghost's answer -

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scrollView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingTop="12dp"
    android:paddingBottom="20dp"
    android:scrollbarStyle="outsideOverlay" >


    <LinearLayout
        android:id="@+id/linearLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" 
        android:layout_gravity="center_horizontal"
        android:gravity="center_horizontal">

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="check" 
            android:gravity="center_vertical|center_horizontal"/>
    </LinearLayout>

</ScrollView>
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
ProgDevCode
  • 138
  • 2
  • 13
  • 1
    This solves the cutting the top off problem. But there is still one problem with this solution. The ScrollView content was not centered vertically. But this can be fixed by setting the following values of the ScrollView: android:layout_height="wrap_content" android:layout_gravity="center_vertical" – Patrick Boos Aug 18 '14 at 09:52
  • I have found that for this to work within other layouts, the top ScrollView must be embedded within a FrameLayout. – Theo Jul 20 '16 at 21:26
1

One thing to consider is what NOT to set. Make certain your child controls, especially EditText controls, do not have the RequestFocus property set.

This may be one of the last interpreted properties on the layout and it will override gravity settings on its parents (layout or ScrollView).

Abhishek Garg
  • 3,092
  • 26
  • 30
0

using the scroll view inside the ConstraintLayout. It is worked for me

<androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@android:color/white">

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

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" />
            </ScrollView>
        </androidx.constraintlayout.widget.ConstraintLayout>

Scroll view height should be wrap_content

<ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"