sem gravidade para scrollview. como fazer o conteúdo dentro do scrollview como centro

104

Eu quero o conteúdo dentro de scrollView como centro.

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

Nota: não há android:gravityatributo para scrollvew.

qualquer sol: -

Padma Kumar
fonte

Respostas:

175

Eu tive o mesmo problema e finalmente descobri. Isso é para uma vertical ScrollView.

Coloque o seu ScrollViewinterior a RelativeLayoute centralize-o no RelativeLayout. Para que isso funcione, você ScrollViewdeve ter

android:layout_height="wrap_content"

É assim que o código final deve ser:

<?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>
hadi
fonte
29
Esta parece funcionar melhor para mim do que a resposta aceita. Obrigado!
Patrick Boos
Idealmente, o Android deve examinar esses problemas quando houver uma hierarquia de layout. Também deve fornecer as duas opções de rolagem (horizontal / vertical) em um scrollview.BTW thanks @hadi
mayank_droid
2
Isso é meio que um hack, então, embora funcione bem, parece errado.
DariusL
3
Ei está funcionando, mas não rola quando o teclado está visível, tentei adicionar no manifesto android:windowSoftInputMode="stateHidden|adjustResize", mas não rola, me ajude por favor
Helio Soares Junior
3
Não há necessidade de usar RelativeLayoutvisão pesada como raiz. Pode ser FrameLayoute android:layout_gravity="center_vertical"porScrollView
GrafOrlov
148

Que tal agora?

<?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>
Fantasma
fonte
2
sim! Que tal isso! Isso funcionou fantasticamente para mim, então muito obrigado, gentil senhor.
RileyE
Impressionante! Isso me salvou também! Obrigado :)
marienke
101
Existe um problema com isso. Se o conteúdo do ScrollView for maior do que o scrollview, ele ainda irá centralizá-lo e cortar o conteúdo no topo (não tenho certeza ainda porque). O que significa que você não pode rolar até lá.
Patrick Boos
7
PatrickBoos está certo; isso não parece funcionar. Use a resposta do hadi abaixo, centralizando verticalmente a visualização em rolagem em um RelativeLayout.
Mason Lee
Sim, desta forma tem bug, conteúdo maior que scrollView, o conteúdo não vai rolar para cima, seu topo é número negativo, estranho :(
Kross
98

Eu acho que uma solução mais elegante seria usar o ScrollView's android:fillViewportpropriedade. A ScrollViewé um pouco diferente na forma como trata sua visualização de conteúdo (só pode ter uma), mesmo se você definir match_parent( fill_parent) como ScrollView, não dará tanto espaço para sua visualização de conteúdo, em vez disso, o comportamento padrão é ScrollViewenvolver o conteúdo, independentemente do que você especificar para essa exibição. O que android:fillViewportfaz é dizer ao ScrollViewpara esticar seu conteúdo para preencher a janela de visualização ( http://developer.android.com/reference/android/widget/ScrollView.html#attr_android:fillViewport ). Portanto, neste caso, seu LinearLayoutseria esticado para coincidir com a janela de visualização e se a altura ficar atrás da janela de visualização, então será rolável, o que é exatamente o que você deseja!

A resposta aceita não funcionará corretamente quando o conteúdo se estender além de ScrollViewporque ainda centralizará a visualização do conteúdo primeiro, fazendo com que corte uma parte da visualização, e ScrollViewcentralizado em outro layout funciona, mas não parece certo, além do Acho que também resultará em um erro de lint (pai inútil ou algo parecido).

Experimente algo assim:

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

Apenas lembre-se de que o motivo pelo qual ele está sendo centralizado agora é por causa do android:gravityno, LinearLayoutjá que o ScrollViewesticará, LinearLayoutentão tenha isso em mente dependendo do que você adicionar ao layout.

Outra boa leitura, ScrollViewembora não sobre centralização, mas sobre, fillViewporté http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/

Brian Ethier
fonte
11
Esta parece ser a implementação mais correta, sem visualizações extras necessárias.
DariusL
1
Boa solução, parece ser a mais limpa para mim. Obrigado por isso
Benjamin Scharbau
2
Funciona melhor do que a resposta aceita, você me economizou muito tempo! Brian Ethier muito bem fechado!
Mattia Ruggiero
Esta é a solução correta, por todos os motivos descritos nela. Se você tentar a solução acima, e sua visualização de rolagem for mais larga que sua tela, você realmente terá parte de sua visualização de rolagem inacessível e não será capaz de rolar até ela. . Isso deve ser aceito como a solução adequada
Speckpgh 01 de
1
Stackoverflow típico .. a solução correta geralmente está em algum lugar no meio.
Teovald
14

Use este atributo em ScrollView

android:fillViewport="true"

Exemplo

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

Certifique-se de usar Single Child em ScrollView assim como no exemplo acima, que é Relativelayout.

Abhishek Garg
fonte
@JoshuaKing pode porque é uma pergunta de 7 anos e eu postei essa resposta recentemente, 9 meses atrás.
Abhishek Garg
Ha! oh .. verdade. “Bem, funcionou perfeitamente! Obrigado!
Joshua King
1
Esta deve ser definitivamente a resposta aceita! Ele funciona perfeitamente e centraliza um ScrollView se o conteúdo for menor que o tamanho do contêiner. Funciona para ScrollView e HorizontalScrollView. Muito obrigado! 💝💖
Ray Li
isso pode ter o efeito indesejado de esticar seu conteúdo dentro da visualização de rolagem
martinseal1987
@ martinseal1987 acho que o efeito dependerá de seu componente filho, de como você faz o design do seu layout, embora se isso não funcionar para você, você pode fazer seu próprio componente de exibição de rolagem personalizado de acordo com suas necessidades de design e trabalho. e também compartilhe a captura de tela do resultado desejado comigo, para que eu possa analisar e fornecer sua solução mais melhor e funcional. pronto para ajudar. Felicidades.
Abhishek Garg
9

Para @Patrick_Boss - o que impediu o corte do conteúdo em meu aplicativo foi alterar gravity e layout_gravity para center_horizontal para o LinearLayout.

Funcionou para mim ... mas não tenho certeza se funcionará para você.

Modificação da resposta de @ 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
fonte
1
Isso resolve o problema de corte do topo. Mas ainda há um problema com essa solução. O conteúdo ScrollView não foi centralizado verticalmente. Mas isso pode ser corrigido definindo os seguintes valores de ScrollView: android: layout_height = "wrap_content" android: layout_gravity = "center_vertical"
Patrick Boos
Descobri que, para que isso funcione em outros layouts, o ScrollView superior deve ser incorporado a um FrameLayout.
Theo
1

Uma coisa a se considerar é o que NÃO definir . Certifique-se de que seus controles filho, especialmente os EditTextcontroles, não tenham a RequestFocuspropriedade definida.

Esta pode ser uma das últimas propriedades interpretadas no layout e substituirá as configurações de gravidade em seus pais ( layoutou ScrollView).

Epsilon3
fonte
0

usando a visualização de rolagem dentro do ConstraintLayout. Funcionou para mim

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

A altura da visualização de rolagem deve ser wrap_content

<ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
Hariharan Kanakaraja
fonte