brak grawitacji dla scrollview. jak sprawić, by treść znajdowała się wewnątrz scrollview as center


105

Chcę, aby zawartość wewnątrz scrollView była w środku.

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

Uwaga: nie ma android:gravityatrybutu dla scrollvew.

dowolny sol: -

Odpowiedzi:


176

Miałem ten sam problem i w końcu to rozgryzłem. To jest dla pionu ScrollView.

Umieść swoje ScrollViewwnętrze a RelativeLayouti wyśrodkuj je w RelativeLayout. Aby to zadziałało, ScrollViewpowinieneś

android:layout_height="wrap_content"

Tak powinien wyglądać ostateczny kod:

<?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
Ta wydaje mi się działać lepiej niż zaakceptowana odpowiedź. Dziękuję Ci!
Patrick Boos

Idealnie byłoby, gdyby Android zajął się tym problemem, gdy istnieje hierarchia układu. Powinien również zapewnić obie opcje przewijania (w poziomie / w pionie) w jednym widoku przewijania. Dzięki BTW @hadi
mayank_droid

2
To trochę hackowanie, więc chociaż działa dobrze, wydaje się złe.
DariusL

3
Hej, działa, ale nie przewija się, gdy klawiatura jest widoczna, próbowałem dodać w manifeście, android:windowSoftInputMode="stateHidden|adjustResize"ale nie przewijaj, pomóż mi
Helio Soares Junior

3
Nie ma potrzeby używania ciężkiego RelativeLayoutjako widoku głównego. To może być FrameLayouti android:layout_gravity="center_vertical"dlaScrollView
GrafOrlov

148

Co powiesz na to?

<?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
Tak! Co ty na to! To zadziałało dla mnie fantastycznie, więc bardzo dziękuję, uprzejmy panie.
RileyE,

Niesamowite! To też mnie uratowało! Dzięki :)
marienke

101
Jest z tym jeden problem. Jeśli zawartość w ScrollView jest większa niż widok przewijania, nadal będzie ją wyśrodkowywać i odcinać zawartość u góry (nie wiem jeszcze, dlaczego). Oznacza to, że nie możesz tam przewijać.
Patrick Boos

7
PatrickBoos ma rację; to nie działa. Użyj odpowiedzi hadi poniżej, wyśrodkowując widok przewijania w pionie w RelativeLayout.
Mason Lee

Tak, w ten sposób mam błąd, zawartość większa niż scrollView, zawartość nie przewinie się do góry, jego góra to liczba ujemna, dziwne :(
Kross

98

Myślę, że bardziej eleganckim rozwiązaniem byłoby skorzystać z ScrollView„s android:fillViewportnieruchomości. A ScrollViewjest trochę inny w sposobie, w jaki traktuje swój widok zawartości (może mieć tylko jeden), nawet jeśli ustawisz match_parent( fill_parent) na ScrollViewto, nie da tak dużych odstępów w widoku zawartości, zamiast tego domyślnym zachowaniem jest ScrollViewzawijanie treść niezależnie od tego, co określisz dla tego widoku. Mówi, android:fillViewportże ma ScrollViewrozciągnąć zawartość, aby wypełnić obszar roboczy ( http://developer.android.com/reference/android/widget/ScrollView.html#attr_android:fillViewport ). W tym przypadku LinearLayoutzostanie rozciągnięty, aby dopasować się do widocznego obszaru, a jeśli wysokość znajdzie się za rzutnią, będzie można go przewijać, co jest dokładnie tym, czego chcesz!

Zaakceptowana odpowiedź nie będzie działać poprawnie, gdy zawartość wykracza poza obszar, ScrollViewponieważ nadal będzie wyśrodkowywać widok treści, powodując najpierw odcięcie części widoku, a ScrollViewwyśrodkowany w innym układzie działa, ale po prostu nie wydaje się odpowiedni, poza tym Myślę, że spowoduje to również błąd kłaczków (bezużyteczny rodzic lub coś podobnego).

Spróbuj czegoś takiego:

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

Wystarczy pamiętać, że powodem jest skupione są tu teraz ze względu na android:gravityna LinearLayoutskoro ScrollViewbędzie rozciągnąć LinearLayoutwięc miej to na uwadze, w zależności od tego, co można dodać do układu.

Kolejną dobrą lekturą, ScrollViewchoć nie o centrowaniu, ale o tym, fillViewportjest http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/


11
Wygląda na to, że jest to najbardziej poprawna implementacja, bez dodatkowych widoków.
DariusL

1
Fajne rozwiązanie, wydaje mi się najczystsze. Dzięki za to
Benjamin Scharbau

2
Działa lepiej niż zaakceptowana odpowiedź, zaoszczędziłeś mi dużo czasu! Naprawdę dobra robota, Brian Ethier!
Mattia Ruggiero

Jest to właściwe rozwiązanie z wszystkich opisanych w nim powodów. Jeśli wypróbujesz powyższe rozwiązanie, a widok przewijania jest szerszy niż ekran, część widoku przewijania będzie niedostępna i nie będzie można do niej przewinąć. To powinno zostać zaakceptowane jako właściwe rozwiązanie
Speckpgh

1
Typowy Stackoverflow… prawidłowe rozwiązanie często znajduje się gdzieś pośrodku.
Teovald,

14

Użyj tego atrybutu w ScrollView

android:fillViewport="true"

Przykład

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

Upewnij się, że używasz Single Child w ScrollView, tak jak w powyższym przykładzie, czyli Relativelayout.


@JoshuaKing może, ponieważ ma 7 lat pytanie i opublikowałem tę odpowiedź niedawno 9 miesięcy temu.
Abhishek Garg

Ha! och ... prawda. 😆 Cóż, zadziałało idealnie! Więc dziękuję!
Joshua King

1
To zdecydowanie powinna być akceptowana odpowiedź! Działa doskonale i wyśrodkowuje ScrollView, jeśli zawartość jest mniejsza niż rozmiar kontenera. Działa zarówno dla ScrollView, jak i HorizontalScrollView. Dziękuję bardzo! 💝💖
Ray Li

może to mieć niezamierzony efekt rozciągania treści w widoku przewijania
martinseal1987,

@ martinseal1987 Myślę, że efekt będzie zależał od twojego komponentu podrzędnego, od tego, jak tworzysz projekt układu, chociaż jeśli to nie zadziała, możesz stworzyć własny niestandardowy komponent widoku przewijania zgodnie ze swoimi potrzebami projektowymi i roboczymi. a także udostępnij mi zrzut ekranu z żądanym wynikiem, abym mógł przyjrzeć się i zapewnić lepsze i działające rozwiązanie. gotowy do pomocy. Twoje zdrowie.
Abhishek Garg

9

Dla @Patrick_Boss - tym, co powstrzymało wycinanie treści w mojej aplikacji, była zmiana gravity i layout_gravity na center_horizontal dla LinearLayout.

U mnie zadziałało ... ale nie jestem pewien, czy to zadziała.

Modyfikacja odpowiedzi @ 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>

1
To rozwiązuje problem odcinania wierzchołka. Ale z tym rozwiązaniem wciąż jest jeden problem. Zawartość ScrollView nie została wyśrodkowana w pionie. Ale można to naprawić, ustawiając następujące wartości ScrollView: android: layout_height = "wrap_content" android: layout_gravity = "center_vertical"
Patrick Boos

Zauważyłem, że aby to działało w innych układach, górny ScrollView musi być osadzony w FrameLayout.
Theo

1

Jedną rzeczą do rozważenia jest to, czego NIE ustawiać . Upewnij się, że kontrolki podrzędne, zwłaszcza EditTextkontrolki, nie mają RequestFocusustawionej właściwości.

Może to być jedna z ostatnich zinterpretowanych właściwości w układzie i zastąpi ustawienia grawitacji w jego rodzicach ( layoutlub ScrollView).


0

używając widoku przewijania wewnątrz ConstraintLayout. To działa dla mnie

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

Wysokość widoku przewijania powinna wynosić wrap_content

<ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.