Center content in scroll view
Asked Answered
K

11

39

I want to center my LinearLayout within ScrollView. When LinearLayout's height is small it's centered alright (see image #1) but when LinearLayout's height is bigger than the screen's height then it behaves strange. I cannot see the top of LinearLayout (see image #2) and at the bottom of ScrollView there's huge padding. I don't know what's happening here. When there are lots of content in LinearLayout the whole screen should look like in image #3.

image #1
image #2
image #3

Here's my layout file:

            <?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:background="#cccfff" >

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:layout_margin="28dp"
                    android:background="#ffffff"
                    android:orientation="vertical"
                    android:paddingBottom="40dp"
                    android:paddingLeft="20dp"
                    android:paddingRight="20dp"
                    android:paddingTop="40dp" >

                    <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="16dp"
                        android:src="@drawable/ic_launcher" />

                    <TextView
                        android:id="@+id/tip_title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="12dp"
                        android:text="Title"
                        android:textColor="@color/orange_text"
                        android:textSize="@dimen/font_size_medium" />

                    <TextView
                        android:id="@+id/tip_description"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Description description..."
                        android:textSize="@dimen/font_size_small" />
                </LinearLayout>

            </ScrollView>
Koski answered 23/10, 2013 at 11:24 Comment(2)
set layout_gravity = center for the views to be centeredElul
You, sir, deserve an upvote for "Push the tempo, push the tempo, push the tempo, push the tempo"Yeorgi
Q
86

You can use android:fillViewport="true" to center the content. Something like this:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">
        <!-- content -->
</ScrollView>
Questionless answered 12/11, 2015 at 2:52 Comment(6)
This is a better solution. It does not involve the creation of a useless LinearLayout in the hierarchy.Feaze
Excellent! layout_gravity to center in LinearLayout caused it to hide content below toolbar. This one worked!Haemoid
This doesn't work. I just did it and buttons align to the left as if nothing happened.Discography
Why would this work? The content still will be out of bounds if the gravity is set to centerToluol
android:fillViewport="true" will just cause your child layout to match size of ScrollView (match_parent essentially). You would also need to set gravity to your child layout in order for this to work.Estefanaestel
This solution didn't work for me. Just adding android:fillViewport didn't center ScrollView's content and additionally having android:layout_gravity="center_vertical" still cut off top views. @Vladimir workaround below worked, thou.Haematite
B
40

You should use an external horizontal LinearLayout. It's working for me in the same situation.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="horizontal" >
    <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
        <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal" >
            <TextView
                    android:text="@string/your_text"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>
</LinearLayout>
Burgee answered 11/12, 2013 at 15:25 Comment(0)
K
15

And this is how you center a view inside a ConstraintLayout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="#86c2e1"
        android:elevation="4dp"
        app:layout_constraintTop_toTopOf="parent"
        app:title="Toolbar" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="#eda200"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHeight_default="wrap"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        app:layout_constraintVertical_bias="0.5">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/lorem_ipsum"
            android:textSize="20sp" />
    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

enter image description here

Koski answered 11/2, 2020 at 10:8 Comment(1)
Thank you! Very clever and I don't think I would have easily come up with this. I don't have the tool bar (just filling the screen), but this worked exactly as I wanted, centering smaller content and starting longer content at the top, with scrolling enabled. Perfect!Literati
P
2

Set focus on your top most UI component which you want to see

<ImageView
            android:focusable="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:src="@drawable/ic_launcher" />
Paraldehyde answered 23/10, 2013 at 11:53 Comment(0)
H
2
<ScrollView
android:id="@id/scrool_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">

<LinearLayout
    android:id=="@id/direct_child"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.cardview.widget.CardView
        android:id=="@id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:visibility="visible"
        app:cardPreventCornerOverlap="true"
        app:cardUseCompatPadding="true"
        card_view:cardCornerRadius="5dp"
        card_view:cardElevation="10dp">

    </androidx.cardview.widget.CardView>
</LinearLayout></ScrollView>

You need to do 3 things:

  1. Set android:fillViewport="true" in ScrollView
  2. The direct child of the ScroolView needs to be a LinearLayout
  3. Your original Content will be under LinearLayout and for the Content set android:layout_gravity="center_vertical"

These 3 things will ensure the following:

  1. When the Content is Small, it will be centered-vertically in ScrollView.
  2. When the Content is Large, it will be scrolled normally.
Hildegard answered 5/10, 2021 at 9:25 Comment(0)
H
0

Try this may satisfy your requirement.

   <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#cccfff"
    android:gravity="center"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_margin="10dp"
        android:background="#ffffff"
        android:gravity="center_vertical"
        android:orientation="vertical"
        android:paddingBottom="40dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:paddingTop="40dp" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:src="@drawable/ic_launcher" />

        <TextView
            android:id="@+id/tip_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="12dp"
            android:text="Title" />

        <TextView
            android:id="@+id/tip_description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="biruDescription description..." />
    </LinearLayout>

</LinearLayout>

One more line in your java code

TextView tip_description = (TextView) findViewById(R.id.tip_description);
        tip_description.setMovementMethod(new ScrollingMovementMethod());

This will scroll your description content rather whole layout.

Hyaluronidase answered 23/10, 2013 at 11:47 Comment(2)
LinearLayout is not centered vertically when tip_description text is short.Koski
Well this is the best solution so far but I wish whole LinearLayout is scrollable not just the TextView inside it. I've been googling for an hour and now I'm having an impression that it's not possible to have what I want. Oh well...Koski
R
0
<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
           xmlns:android="http://schemas.android.com/apk/res/android"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:orientation="vertical"
           android:gravity="center"
           android:padding="10dp"
           android:background="#cccfff">

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

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:layout_margin="28dp"
                    android:background="#ffffff"
                    android:orientation="vertical"
                    android:paddingBottom="40dp"
                    android:paddingLeft="20dp"
                    android:paddingRight="20dp"
                    android:paddingTop="40dp" >

                    <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="16dp"
                        android:src="@drawable/ic_launcher" />

                    <TextView
                        android:id="@+id/tip_title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="12dp"
                        android:text="Title"
                        android:textColor="@color/orange_text"
                        android:textSize="@dimen/font_size_medium" />

                    <TextView
                        android:id="@+id/tip_description"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Description description..."
                        android:textSize="@dimen/font_size_small" />
                </LinearLayout>

            </ScrollView>
</LinearLayout>
Radiotelegraphy answered 23/10, 2013 at 11:51 Comment(0)
H
0

Just use my CenteringLinearLayout class below.

import android.content.Context
import android.support.constraint.ConstraintLayout
import android.util.AttributeSet
import android.view.View
import android.widget.LinearLayout

class CenteringLinearLayout: LinearLayout {

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context) : super(context)

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        val parentView = this.parent as View
        if (h > parentView.height) {
            parentView.post {
                val params = parentView.layoutParams as ConstraintLayout.LayoutParams
                params.height = ConstraintLayout.LayoutParams.MATCH_CONSTRAINT
                parentView.layoutParams = params
            }
        } else {
            val params = parentView.layoutParams
            params.height = ConstraintLayout.LayoutParams.WRAP_CONTENT
            parentView.layoutParams = params
        }
        super.onSizeChanged(w, h, oldw, oldh)
    }
}
Highbred answered 2/12, 2018 at 13:11 Comment(0)
Y
0

I simply did some calculations and added android:layout_marginLeft & android:layout_marginRight and that did the work for me.

Yelp answered 14/12, 2021 at 11:18 Comment(2)
Doing this will center the content horizontally only. And it will not work always.Luong
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Chablis
O
-1

Try putting the margin and paddings to the ScrollView

Ondometer answered 23/10, 2013 at 11:30 Comment(1)
That doesn't help. First of all my ScrollView cannot have margins. It has to take the whole screen. Also it cannot have paddings because these paddings are also applied to ScrollView's scroll bar on the right and scroll bar should be able to scroll from top to the bottom of the screen.Koski
E
-1

Maybe it is unclear how layout works. In your case you need to set an external layout that fills the parent and has gravity set as center, inside have a scroll view with layout height wrap_content and internal layout with layout height wrap_content also. Then External layout will center scroll view if it is smaller.

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center">

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

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

        <!-- Content here -->

        </LinearLayout>
    </ScrollView>
</LinearLayout>
Elmaelmajian answered 1/5, 2015 at 21:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.