нет гравитации для прокрутки. как сделать контент внутри scrollview как центр

105

Я хочу, чтобы содержимое внутри scrollView находилось в центре.

<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>

Примечание:android:gravity для scrollvew нет атрибута.

любой соль: -

Падма Кумар
источник

Ответы:

176

У меня была такая же проблема, и я наконец понял ее. Это для вертикали ScrollView.

Поместите ScrollViewвнутрь a RelativeLayoutи центрируйте его в RelativeLayout. Чтобы это сработало, у вас ScrollViewдолжен быть

android:layout_height="wrap_content"

Вот как должен выглядеть окончательный код:

<?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>
хади
источник
29
Этот, кажется, работает для меня лучше, чем принятый ответ. Спасибо!
Патрик Боос,
В идеале Android должен изучить эти проблемы при наличии иерархии макета. Также должен обеспечивать оба варианта прокрутки (горизонтальный / вертикальный) в одном режиме прокрутки.BTW спасибо @hadi
mayank_droid
2
Это своего рода взлом, поэтому, хотя он работает нормально, это кажется неправильным.
DariusL
3
Привет, он работает, но не прокручивается, когда отображается клавиатура, я попытался добавить в манифест, android:windowSoftInputMode="stateHidden|adjustResize"но не прокручивайте, помогите мне, пожалуйста
Helio Soares Junior
3
Нет необходимости использовать тяжелый RelativeLayoutвид в качестве корневого. Может быть FrameLayoutи android:layout_gravity="center_vertical"заScrollView
ГрафОрлов 08
148

Как насчет этого?

<?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>
Призрак
источник
2
Да! Как насчет этого! У меня это сработало фантастически, так что большое спасибо, добрый сэр.
RileyE
Потрясающие! Это меня тоже спасло! Спасибо :)
marienke
101
С этим есть одна проблема. Если ваш контент в ScrollView больше, чем в scrollview, он все равно будет центрировать его и обрезать контент вверху (хотя еще не уверен, почему). Это означает, что вы не можете прокручивать там.
Патрик Боос,
7
Патрик Бус прав; похоже, это не работает. Используйте ответ hadi ниже, вертикально центрируя прокрутку в RelativeLayout.
Мейсон Ли
Да, у этого способа есть ошибка, контент больше, чем scrollView, контент не будет прокручиваться вверх, его вершина - отрицательное число, странно :(
Kross
98

Я думаю, что более элегантное решение было бы использовать в ScrollView«S android:fillViewportсобственности. A ScrollViewнемного отличается в том, как он обрабатывает свое представление содержимого (может иметь только один), даже если вы установили match_parent( fill_parent) в, ScrollViewон не будет давать такой большой интервал для его представления содержимого, вместо этого поведение по умолчанию заключается в том, ScrollViewчтобы обернуть контент независимо от того, что вы указали для этого представления. Что android:fillViewportозначает, что ScrollViewнужно растянуть содержимое, чтобы заполнить область просмотра ( http://developer.android.com/reference/android/widget/ScrollView.html#attr_android:fillViewport ). Итак, в этом случае ваш LinearLayoutбудет растянут, чтобы соответствовать области просмотра, и если высота будет позади области просмотра, тогда она будет прокручиваемой, что именно то, что вы хотите!

Принятый ответ не будет работать должным образом, когда контент выходит за пределы, ScrollViewпотому что он по-прежнему будет ScrollViewцентрировать представление содержимого, сначала заставляя его отрезать часть представления, а центрирование в другом макете работает, но просто не кажется правильным, кроме того Я думаю, что это также приведет к ошибке lint (бесполезный родитель или что-то в этом роде).

Попробуйте что-то вроде этого:

<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>

Просто помните, что причина, по которой он сейчас центрируется здесь, заключается в android:gravityтом, LinearLayoutчто он ScrollViewбудет растягиваться, LinearLayoutпоэтому имейте это в виду в зависимости от того, что вы добавляете в макет.

Еще один хороший читать дальше , ScrollViewхотя и не о сосредоточении , а о fillViewportявляется http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/

Брайан Этье
источник
11
Это выглядит как наиболее правильная реализация, дополнительных просмотров не требуется.
DariusL
1
Хорошее решение, кажется, для меня самое чистое. Спасибо за это
Бенджамин Шарбау
2
Работает лучше, чем принятый ответ, вы сэкономили мне много времени! Действительно молодец, Брайан Этье!
Маттиа Руджеро
Это правильное решение по всем причинам, описанным в нем. Если вы попробуете решение, указанное выше, и ваша прокрутка будет шире, чем ваш экран, у вас действительно будет часть вашей прокрутки недоступна, и вы не сможете прокрутить до нее .. . Это следует принять как правильное решение
Speckpgh 01
1
Типичный Stackoverflow ... правильное решение часто находится где-то посередине.
Teovald
14

Используйте этот атрибут в ScrollView

android:fillViewport="true"

пример

 <?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>

Обязательно используйте Single Child в ScrollView, как в примере выше, Relativelayout.

Абхишек Гарг
источник
@JoshuaKing может, потому что этому вопросу 7 лет, и я опубликовал этот ответ недавно, 9 месяцев назад.
Abhishek Garg
Ха! ой .. правда. 😆Ну, отлично сработало! Так что спасибо!
Джошуа Кинг
1
Это определенно должен быть принятый ответ! Он отлично работает и центрирует ScrollView, если содержимое меньше размера контейнера. Работает как для ScrollView, так и для HorizontalScrollView. Спасибо вам большое! 💝💖
Рэй Ли
это может привести к непреднамеренному эффекту растягивания вашего контента внутри прокрутки
martinseal1987
@ martinseal1987 Я думаю, что эффект будет зависеть от вашего дочернего компонента, от того, как вы делаете дизайн макета, хотя, если это не сработает для вас, вы можете создать свой собственный компонент просмотра прокрутки в соответствии с вашим дизайном и рабочими потребностями. и, пожалуйста, также поделитесь со мной скриншотом желаемого результата, чтобы я мог изучить и предоставить вам более лучшее и рабочее решение. готовы помочь. ура.
Абхишек
9

Для @Patrick_Boss - то, что остановило вырезание контента в моем приложении, было изменение гравитации и layout_gravity на center_horizontal для LinearLayout.

У меня это сработало ... но не уверен, сработает ли это для вас.

Модификация ответа @ Ghost -

<?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>
ProgDevCode
источник
1
Это решает проблему срезания верхушки. Но есть еще одна проблема с этим решением. Содержимое ScrollView не было центрировано по вертикали. Но это можно исправить, установив следующие значения ScrollView: android: layout_height = "wrap_content" android: layout_gravity = "center_vertical"
Патрик Боос
Я обнаружил, что для того, чтобы это работало в других макетах, верхний ScrollView должен быть встроен в FrameLayout.
Тео
1

Следует учитывать, что НЕ устанавливать . Убедитесь , что ваши дочерние элементы, особенно EditTextэлементы управления, не имеют RequestFocusнабор свойств.

Это может быть одно из последних интерпретируемых свойств в макете, и оно переопределит настройки гравитации для своих родителей ( layoutили ScrollView).

Эпсилон3
источник
0

используя вид прокрутки внутри ConstraintLayout. Это сработало для меня

<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>

Высота прокрутки должна быть wrap_content

<ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
Харихаран Канакараджа
источник