Posso scorrere uno ScrollView a livello di codice in Android?


145

C'è un modo per scorrere ScrollViewprogrammaticamente fino a una determinata posizione?

Ho creato una dinamica TableLayoutche si trova in a ScrollView. Quindi voglio che su un'azione specifica (come fare clic su un pulsante, ecc.) La riga particolare debba scorrere automaticamente fino alla prima posizione.

È possibile?

Risposte:


165
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getBottom());

o

sv.scrollTo(5, 10);


43
Combinando la risposta di ercu e un commento fatto su di essa, il modo migliore sembra essere:mScrollView.post(new Runnable() { public void run() { mScrollView.fullScroll(View.FOCUS_DOWN); } });
sparrowt

2
scrollTo () non produrrà la ricomposizione del desiderio. Si dovrebbe andare con fullScroll ()
Amit Yadav,

3
Scorrimento più piacevole è con effetto naturale: sv.smoothScrollTo (5, 10)
ivan.panasiuk,

205

La risposta di Pragna non funziona sempre, prova questo:

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.scrollTo(0, mScrollView.getBottom());
        } 
});

o

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
        } 
});

se si desidera scorrere per iniziare

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_UP);
        } 
});

28
Ho usato mScrollView.fullScroll(mScrollView.FOCUS_DOWN);con successo.
amcc

3
Posso confermare i risultati di Vanthel. mScrollView.fullScroll in un post eseguibile ha fatto il trucco.
AlanKley,

1
Eccellente! In effetti, senza Runnable, non ha funzionato. Ora funziona ! :)
Regis_AG,

5
@HiteshDhamshaniya Se vuoi una pergamena liscia, prova mScrollView.smoothScrollTo(0, mScrollView.getBottom());.
Mike Ortiz,

1
Perché ha bisogno postqui?
Liutaio

35

Volevo che scrollView scorresse direttamente dopo onCreateView () (non dopo, ad esempio, un clic sul pulsante). Per farlo funzionare avevo bisogno di usare un ViewTreeObserver:

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    mScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        }
    });

Ma attenzione che questo verrà chiamato ogni volta che qualcosa viene impaginato (ad esempio se imposti una vista invisibile o simile), quindi non dimenticare di rimuovere questo ascoltatore se non ti serve più con:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) su SDK Liv. <16

o

public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) in SDK Lvl> = 16


23

Ci sono molte buone risposte qui, ma voglio solo aggiungere una cosa. A volte capita di voler scorrere ScrollView fino a una vista specifica del layout, invece di uno scorrimento completo verso l'alto o verso il basso.

Un semplice esempio: in un modulo di registrazione, se l'utente tocca il pulsante "Iscriviti" quando un testo di modifica del modulo non è compilato, si desidera scorrere fino a quel testo di modifica specifico per dire all'utente che deve riempire quel campo.

In tal caso, puoi fare qualcosa del genere:

scrollView.post(new Runnable() { 
        public void run() { 
             scrollView.scrollTo(0, editText.getBottom());
        } 
});

oppure, se si desidera uno scorrimento uniforme anziché uno scorrimento istantaneo:

scrollView.post(new Runnable() { 
            public void run() { 
                 scrollView.smoothScrollTo(0, editText.getBottom());
            } 
    });

Ovviamente puoi usare qualsiasi tipo di vista invece di Modifica testo. Si noti che getBottom () restituisce le coordinate della vista in base al layout principale, quindi tutte le viste utilizzate all'interno di ScrollView dovrebbero avere solo un padre (ad esempio un layout lineare).

Se hai più genitori all'interno del figlio di ScrollView, l'unica soluzione che ho trovato è chiamare requestChildFocus nella vista padre:

editText.getParent().requestChildFocus(editText, editText);

ma in questo caso non è possibile avere uno scorrimento regolare.

Spero che questa risposta possa aiutare qualcuno con lo stesso problema.


1
@JohnT Sono contento che ti abbia aiutato :)
Mattia Ruggiero,

20

Usa qualcosa del genere:

mScrollView.scrollBy(10, 10);

o

mScrollView.scrollTo(10, 10);


8

Se vuoi scorrere istantaneamente, puoi usare:

ScrollView scroll= (ScrollView)findViewById(R.id.scroll);
scroll.scrollTo(0, scroll.getBottom());

            OR

scroll.fullScroll(View.FOCUS_DOWN);

            OR

scroll.post(new Runnable() {            
    @Override
    public void run() {
           scroll.fullScroll(View.FOCUS_DOWN);              
    }
});

O se vuoi scorrere senza intoppi e lentamente in modo da poter usare questo:

private void sendScroll(){
        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {Thread.sleep(100);} catch (InterruptedException e) {}
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.fullScroll(View.FOCUS_DOWN);
                    }
                });
            }
        }).start();
    }

cosa fa quel catchblocco?
John Sardinha,

1
Il blocco cattura consente di rilevare le eccezioni durante lo scorrimento, se presenti.
Maddy,

5

** per scorrere fino all'altezza desiderata. Ho trovato una buona soluzione **

                scrollView.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.scrollBy(0, childView.getHeight());
                    }
                }, 100);

4

Ho ottenuto questo per funzionare per scorrere fino alla fine di un ScrollView (con un TextView all'interno):

(Ho messo questo su un metodo che aggiorna TextView)

final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
    myScrollView.post(new Runnable() {
    public void run() {
        myScrollView.fullScroll(View.FOCUS_DOWN);
    }
});

4

Si, puoi.

Diciamo che ne hai uno Layoute dentro quello hai molti Views. Quindi, se vuoi scorrere fino a uno Viewa livello di codice, devi scrivere il seguente frammento di codice:

Per esempio:

content_main.xml

<ScrollView
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

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

        <Button
            android:id="@+id/btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/txtView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>
</ScrollView>

MainActivity.java

ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
Button btn = (Button) findViewById(R.id.ivEventBanner);
TextView txtView = (TextView) findViewById(R.id.ivEditBannerImage);

Se vuoi scorrere fino a uno specifico View, diciamo txtview , in questo caso scrivi semplicemente:

scrollView.smoothScrollTo(txtView.getScrollX(),txtView.getScrollY());

E il gioco è fatto.


3

Nota: se sei già in una discussione, devi creare una nuova discussione di post, o non scorrere la nuova altezza lunga fino alla fine (per me). Ad esempio:

void LogMe(final String s){
    runOnUiThread(new Runnable() {
        public void run() {
            connectionLog.setText(connectionLog.getText() + "\n" + s);
            final ScrollView sv = (ScrollView)connectLayout.findViewById(R.id.scrollView);
            sv.post(new Runnable() {
                public void run() {
                    sv.fullScroll(sv.FOCUS_DOWN);
                    /*
                    sv.scrollTo(0,sv.getBottom());
                    sv.scrollBy(0,sv.getHeight());*/
                }
            });
        }
    });
}

3

Aggiunta di un'altra risposta che non comporta coordinate.

Ciò consentirà di mettere a fuoco la vista desiderata (ma non nella posizione più alta):

  yourView.getParent().requestChildFocus(yourView,yourView);

void pubblico RequestChildFocus (Visualizza figlio, Visualizza focalizzato)

child - Il figlio di questo ViewParent che desidera concentrarsi. Questa vista conterrà la vista focalizzata. Non è necessariamente la visione che in realtà ha il focus.

focalizzato - La vista che è un discendente del bambino che in realtà ha il focus


Esattamente quello di cui avevo bisogno, grazie. Attiva prima l'attivazione per la vista di scorrimento e quindi scrollView.smoothScrollTo (0, scrollView.getChildAt (0) .getBottom ());
Vulovic Vukasin l'

3

basta scorrere la pagina:

ScrollView sv = (ScrollView) findViewById(your_scroll_view);
sv.pageScroll(View.FOCUS_DOWN);

2

Tutti pubblicano risposte così complicate.

Ho trovato una risposta semplice, per lo scorrimento verso il basso, bene:

final ScrollView myScroller = (ScrollView) findViewById(R.id.myScrollerView);

// Scroll views can only have 1 child, so get the first child's bottom,
// which should be the full size of the whole content inside the ScrollView
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );

E, se necessario, puoi inserire la seconda riga di codice, sopra, in un eseguibile:

myScroller.post( new Runnable() {
    @Override
    public void run() {
        myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
    }
}

Mi ci sono volute molte ricerche e giochi per trovare questa semplice soluzione. Spero aiuti anche te! :)


1

Stavo usando Runnable con sv.fullScroll (View.FOCUS_DOWN); Funziona perfettamente per il problema immediato, ma quel metodo fa in modo che ScrollView prenda il Focus da tutto lo schermo, se si fa in modo che AutoScroll avvenga ogni volta, nessun EditText sarà in grado di ricevere informazioni dall'utente, la mia soluzione era usare un codice diverso sotto il runnable:

sv.scrollTo (0, sv.getBottom () + sv.getScrollY ());

fare lo stesso senza perdere di vista punti di vista importanti

saluti.


0

sta funzionando per me

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    mScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        }
    });

0
private int totalHeight = 0;

ViewTreeObserver ScrollTr = loutMain.getViewTreeObserver();
ScrollTr.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            loutMain.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        } else {
            loutMain.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
        TotalHeight = loutMain.getMeasuredHeight();

    }
});

scrollMain.smoothScrollTo(0, totalHeight);

0
I had to create Interface

public interface ScrollViewListener {
    void onScrollChanged(ScrollViewExt scrollView, 
                         int x, int y, int oldx, int oldy);
}    

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;

public class CustomScrollView extends ScrollView {
    private ScrollViewListener scrollViewListener = null;
    public ScrollViewExt(Context context) {
        super(context);
    }

    public CustomScrollView (Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public CustomScrollView (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }
}




<"Your Package name ".CustomScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusableInTouchMode="true"
    android:scrollbars="vertical">

    private CustomScrollView scrollView;

scrollView = (CustomScrollView)mView.findViewById(R.id.scrollView);
        scrollView.setScrollViewListener(this);


    @Override
    public void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {
        // We take the last son in the scrollview
        View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);
        int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));

        // if diff is zero, then the bottom has been reached
        if (diff == 0) {
                // do stuff
            //TODO keshav gers
            pausePlayer();
            videoFullScreenPlayer.setVisibility(View.GONE);

        }
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.