Kann ich eine ScrollView programmgesteuert in Android scrollen?

145

Gibt es eine Möglichkeit, ein ScrollViewProgramm programmgesteuert zu einer bestimmten Position zu scrollen ?

Ich habe eine Dynamik geschaffen, TableLayoutdie in einem platziert ist ScrollView. Ich möchte also, dass bei einer bestimmten Aktion (wie dem Klicken auf eine Schaltfläche usw.) die bestimmte Zeile automatisch zu einer oberen Position gescrollt wird.

Ist es möglich?

Arun Badole
quelle

Antworten:

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

oder

sv.scrollTo(5, 10);

Android
quelle
43
Wenn man die Antwort von ercu und einen Kommentar dazu kombiniert, scheint der beste Weg zu sein:mScrollView.post(new Runnable() { public void run() { mScrollView.fullScroll(View.FOCUS_DOWN); } });
Sparrowt
2
scrollTo () erzeugt kein Wunsch-Resull. Man sollte mit fullScroll ()
Amit Yadav
3
Schönere Schriftrolle ist mit natürlicher Wirkung: sv.smoothScrollTo (5, 10)
ivan.panasiuk
205

Die Antwort aus Pragna funktioniert nicht immer, versuchen Sie Folgendes:

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

oder

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

Wenn Sie zum Starten scrollen möchten

mScrollView.post(new Runnable() { 
        public void run() { 
             mScrollView.fullScroll(mScrollView.FOCUS_UP);
        } 
});
ercu
quelle
28
Ich habe mScrollView.fullScroll(mScrollView.FOCUS_DOWN);mit Erfolg verwendet.
Amcc
3
Ich kann Vanthels Ergebnisse bestätigen. mScrollView.fullScroll in einem Post-Runnable hat den Trick gemacht.
AlanKley
1
Ausgezeichnet ! In der Tat hat es ohne den Runnable nicht funktioniert. Jetzt gehts ! :)
Regis_AG
5
@HiteshDhamshaniya Wenn Sie eine glatte Schriftrolle wünschen, versuchen Sie es mScrollView.smoothScrollTo(0, mScrollView.getBottom());.
Mike Ortiz
1
Warum braucht es posthier?
Liuting
35

Ich wollte, dass die scrollView direkt nach onCreateView () scrollt (nicht nach z. B. einem Klick auf eine Schaltfläche). Damit es funktioniert, musste ich einen ViewTreeObserver verwenden:

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

Beachten Sie jedoch, dass dies jedes Mal aufgerufen wird, wenn etwas geplant wird (z. B. wenn Sie eine unsichtbare oder ähnliche Ansicht festlegen). Vergessen Sie also nicht, diesen Listener zu entfernen, wenn Sie ihn nicht mehr benötigen mit:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) auf SDK Lvl <16

oder

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

Patrick Favre
quelle
23

Hier gibt es viele gute Antworten, aber ich möchte nur eines hinzufügen. Es kommt manchmal vor, dass Sie Ihre ScrollView zu einer bestimmten Ansicht des Layouts scrollen möchten, anstatt vollständig nach oben oder unten zu scrollen.

Ein einfaches Beispiel: Wenn der Benutzer in einem Registrierungsformular auf die Schaltfläche "Anmelden" tippt, wenn ein Bearbeitungstext des Formulars nicht ausgefüllt ist, möchten Sie zu diesem bestimmten Bearbeitungstext scrollen, um dem Benutzer mitzuteilen, dass er dieses Feld ausfüllen muss.

In diesem Fall können Sie so etwas tun:

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

oder, wenn Sie eine glatte Schriftrolle anstelle einer sofortigen Schriftrolle wünschen:

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

Natürlich können Sie jede Art von Ansicht anstelle von Text bearbeiten verwenden. Beachten Sie, dass getBottom () die Koordinaten der Ansicht basierend auf dem übergeordneten Layout zurückgibt, sodass alle in der ScrollView verwendeten Ansichten nur ein übergeordnetes Layout haben sollten (z. B. ein lineares Layout).

Wenn das untergeordnete Element der ScrollView mehrere übergeordnete Elemente enthält, besteht die einzige gefundene Lösung darin, requestChildFocus in der übergeordneten Ansicht aufzurufen:

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

In diesem Fall können Sie jedoch keine glatte Schriftrolle haben.

Ich hoffe, diese Antwort kann jemandem mit dem gleichen Problem helfen.

Mattia Ruggiero
quelle
1
@ JohnT Ich bin froh, dass es dir geholfen hat :)
Mattia Ruggiero
20

Verwenden Sie so etwas:

mScrollView.scrollBy(10, 10);

oder

mScrollView.scrollTo(10, 10);
Srichand Yella
quelle
9

Versuchen Sie es mit der scrollToMethode More Info

Bluefalcon
quelle
8

Wenn Sie sofort scrollen möchten, können Sie Folgendes verwenden:

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);              
    }
});

Oder wenn Sie reibungslos und langsam scrollen möchten, damit Sie Folgendes verwenden können:

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();
    }
Maddy
quelle
Was macht dieser catchBlock?
John Sardinha
1
Der Catch-Block dient zum Abfangen von Ausnahmen während des Bildlaufs, falls gefunden.
Maddy
5

** um zur gewünschten Höhe zu scrollen. Ich habe eine gute Lösung gefunden **

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

Ich habe dies zum Laufen gebracht, um zum Ende einer ScrollView zu scrollen (mit einer TextView darin):

(Ich habe dies auf eine Methode gesetzt, die die Textansicht aktualisiert.)

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

Ja, du kannst.

Nehmen wir an, Sie haben einen Layoutund darin haben Sie viele Views. Wenn Sie also Viewprogrammgesteuert zu einem beliebigen Bildlauf scrollen möchten , müssen Sie den folgenden Codeausschnitt schreiben:

Beispielsweise:

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

Wenn Sie zu einem bestimmten Bildlauf scrollen möchten, Viewsagen wir txtview . In diesem Fall schreiben Sie einfach:

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

Und du bist fertig.

Pankaj Lilan
quelle
3

Hinweis: Wenn Sie bereits in einem Thread sind, müssen Sie einen neuen Post-Thread erstellen, oder es wird keine neue lange Höhe bis zum vollständigen Ende (für mich) gescrollt. Zum Beispiel:

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());*/
                }
            });
        }
    });
}
djdance
quelle
3

Hinzufügen einer weiteren Antwort ohne Koordinaten.

Dadurch wird Ihre gewünschte Ansicht fokussiert (jedoch nicht an die oberste Position):

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

public void RequestChildFocus (Kind anzeigen, Fokussiert anzeigen)

Kind - Das Kind dieses ViewParent, das den Fokus haben möchte. Diese Ansicht enthält die fokussierte Ansicht. Es ist nicht unbedingt die Ansicht, die tatsächlich den Fokus hat.

fokussiert - Die Ansicht, die ein Nachkomme eines Kindes ist, das tatsächlich fokussiert ist

Swas_99
quelle
Genau das, was ich brauchte, danke. Fordern Sie zuerst den Fokus für Ihre Bildlaufansicht und dann scrollView.smoothScrollTo (0, scrollView.getChildAt (0) .getBottom ()) an.
Vulovic Vukasin
3

nur Seite scrollen:

ScrollView sv = (ScrollView) findViewById(your_scroll_view);
sv.pageScroll(View.FOCUS_DOWN);
Kirill Vashilo
quelle
2

Jeder veröffentlicht so komplizierte Antworten.

Ich fand eine einfache Antwort, um ganz nach unten zu scrollen:

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() );

Bei Bedarf können Sie die zweite Codezeile oben in eine ausführbare Datei einfügen:

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

Ich habe viel recherchiert und herumgespielt, um diese einfache Lösung zu finden. Ich hoffe es hilft dir auch! :) :)

Nalorin
quelle
1

Ich habe Runnable mit sv.fullScroll (View.FOCUS_DOWN) verwendet. Es funktioniert perfekt für das unmittelbare Problem, aber diese Methode veranlasst ScrollView, den Fokus vom gesamten Bildschirm zu übernehmen. Wenn Sie dafür sorgen, dass AutoScroll jedes Mal ausgeführt wird, kann kein EditText Informationen vom Benutzer empfangen. Meine Lösung verwendete einen anderen Code unter dem Runnable:

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

das Gleiche tun, ohne den Fokus auf wichtige Ansichten zu verlieren

Schöne Grüße.

Sebasu
quelle
0

es funktioniert für mich

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mScrollView.post(new Runnable() {
                public void run() {
                    mScrollView.fullScroll(View.FOCUS_DOWN);
                }
            });
        }
    });
Ali Asadi
quelle
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);
P. Patel
quelle
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);

        }
    }
Keshav Gera
quelle