Android'de programlı olarak bir ScrollView kaydırabilir miyim?


146

Bir ScrollViewprogramlı olarak belirli bir konuma kaydırmanın herhangi bir yolu var mı ?

Ben dinamiğini oluşturduk TableLayoutbir yerleştirilir ScrollView. Bu nedenle, belirli bir eylemde (bir Düğmeye tıklamak gibi) belirli satırın otomatik olarak en üst konuma kaydırılmasını istiyorum.

Mümkün mü?

Yanıtlar:


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

veya

sv.scrollTo(5, 10);


43
mScrollView.post(new Runnable() { public void run() { mScrollView.fullScroll(View.FOCUS_DOWN); } });
Ercu'nun

2
scrollTo (), arzu edilen resull üretmez. FullScroll () ile gitmeli
Amit Yadav

3
Daha güzel kaydırma doğal efektli: sv.smoothScrollTo (5, 10)
ivan.panasiuk

207

Pragna'nın cevabı her zaman işe yaramıyor, şunu deneyin:

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

veya

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

Başlamak için kaydırmak isterseniz

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

28
mScrollView.fullScroll(mScrollView.FOCUS_DOWN);Başarı ile kullandım .
amcc

3
Vanthel'in bulgularını doğrulayabilirim. Bir post runnable'daki mScrollView.fullScroll hile yaptı.
AlanKley

1
Mükemmel! Gerçekten de Runnable olmadan işe yaramadı. Şimdi çalışıyor ! :)
Regis_AG

5
@HiteshDhamshaniya Sorunsuz bir kaydırma istiyorsanız, deneyin mScrollView.smoothScrollTo(0, mScrollView.getBottom());.
Mike Ortiz

1
Neden postburaya ihtiyacı var?
Liuting

35

ScrollView’un onCreateView () ’den sonra (örneğin bir düğme tıklandıktan sonra değil) doğrudan kaydırmasını istedim. Çalışması için bir ViewTreeObserver kullanmam gerekiyordu:

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

Ancak, bir şey düzenlendiği her seferinde bunun çağrılacağına dikkat edin (örneğin, görünmez veya benzer bir görünüm ayarlarsanız), bu nedenle artık ihtiyacınız yoksa bu dinleyiciyi kaldırmayı unutmayın:

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

veya

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


25

Burada pek çok iyi cevap var ama ben sadece bir şey eklemek istiyorum. Bazen, ScrollView'unuzu yukarı veya aşağıya tam bir kaydırma yerine, düzenin belirli bir görünümüne kaydırmak isteyebilirsiniz.

Basit bir örnek: bir kayıt formunda, kullanıcı formun bir düzenleme metni doldurulmadığında "Kaydol" düğmesine dokunursa, kullanıcıya o alanı doldurması gerektiğini söylemek için o belirli düzenleme metnine kaydırmak istersiniz.

Bu durumda şöyle bir şey yapabilirsiniz:

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

veya hızlı kaydırma yerine yumuşak bir kaydırma istiyorsanız:

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

Açıkçası, Metni Düzenle yerine herhangi bir görünüm türünü kullanabilirsiniz. GetBottom () öğesinin, üst düzenine bağlı olarak görünümün koordinatlarını döndürdüğünü, bu nedenle ScrollView içinde kullanılan tüm görünümlerin yalnızca bir üst öğeye sahip olması gerektiğini (örneğin, Doğrusal Düzen) unutmayın.

ScrollView alt öğesinin içinde birden fazla ebeveyniniz varsa bulduğum tek çözüm, ana görünümde requestChildFocus'u çağırmaktır:

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

ancak bu durumda düzgün bir kaydırma yapamazsınız.

Umarım bu cevap aynı problemi olan birine yardımcı olabilir.


1
@JohnT Sana yardım etmesine sevindim :)
Mattia Ruggiero

19

Bunun gibi bir şey kullanın:

mScrollView.scrollBy(10, 10);

veya

mScrollView.scrollTo(10, 10);


8

Anında kaydırmak istiyorsanız, şunları kullanabilirsiniz:

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

Veya, bunu kullanabilmek için sorunsuz ve yavaş bir şekilde kaydırmak istiyorsanız:

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

bu catchblok ne yapıyor ?
John Sardinha

1
Yakalama bloğu, varsa kaydırma sırasında istisnaları yakalamaktır.
Maddy

5

** istenilen yüksekliğe gitmek için. İyi bir çözüm buldum **

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

4

Bunu bir ScrollView'ın altına kaydırmak için çalıştırdım (içinde bir TextView ile):

(Bunu TextView'i güncelleyen bir yönteme koydum)

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

4

Evet yapabilirsin.

Diyelim ki bir tane var Layoutve içinde çok var Views. Bu nedenle, herhangi bir Viewprogram aracılığıyla kaydırmak istiyorsanız , aşağıdaki kod parçacığını yazmanız gerekir:

Örneğin:

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

Belirli bir yere gitmek istiyorsanız View, txtview diyelim , bu durumda şunu yazın:

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

Ve bitirdiniz.


3

Not: Zaten bir ileti dizisindeyseniz, yeni bir gönderi dizisi oluşturmanız gerekir veya bu, sonuna kadar yeni uzun yüksekliği kaydırmaz (benim için). Örneğin:

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

Koordinatları içermeyen başka bir cevap eklemek.

Bu, istediğiniz görüntünün odaklanmasını sağlar (ancak en üst konuma değil):

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

public void RequestChildFocus (Çocuğu görüntüle, Görüntüle odaklı)

child - Bu ViewParent'ın odak isteyen çocuğu. Bu görünüm odaklanmış görünümü içerecektir. Aslında odak noktası olan görüş olmak zorunda değildir.

odaklanmış - Aslında odak noktası olan çocuğun soyundan gelen görüş


Tam olarak ihtiyacım olan şey, teşekkür ederim. Önce kaydırma görünümünüz için odak isteyin ve ardından scrollView.smoothScrollTo (0, scrollView.getChildAt (0) .getBottom ());
Vulovic Vukasin

3

sadece sayfa kaydırma:

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

2

Herkes çok karmaşık cevaplar veriyor.

En alta kaydırmak için güzel bir cevap buldum:

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

Ve gerekirse, yukarıdaki ikinci kod satırını çalıştırılabilir bir dosyaya koyabilirsiniz:

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

Bu basit çözümü bulmak için çok araştırma yaptım ve etrafta oynadım. Umarım sana da yardımcı olur! :)


1

Runnable'ı sv.fullScroll (View.FOCUS_DOWN) ile kullanıyordum; Acil sorun için mükemmel çalışıyor, ancak bu yöntem ScrollView'ın Odağı tüm ekrandan almasını sağlıyor, bu Otomatik Kaydırmayı her seferinde yaparsanız, hiçbir EditText kullanıcıdan bilgi alamayacak, benim çözümüm farklı bir kod kullanıyordu koşucunun altında:

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

önemli görüşlere odaklanmadan aynı şeyi yapmak

selamlar.


0

benim için çalışıyor

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

        }
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.