क्या मैं एंड्रॉइड में स्क्रॉलव्यू प्रोग्रामेटिक रूप से स्क्रॉल कर सकता हूं?


145

क्या किसी ScrollViewकार्यक्रम को एक निश्चित स्थिति तक स्क्रॉल करने का कोई तरीका है ?

मैंने डायनामिक बनाया है TableLayoutजिसे एक में रखा गया है ScrollView। इसलिए मैं चाहता हूं कि एक विशिष्ट कार्रवाई पर (जैसे एक बटन इत्यादि पर क्लिक करके) विशेष पंक्ति को स्वचालित रूप से एक शीर्ष स्थान पर स्क्रॉल करना चाहिए।

क्या यह संभव है?

जवाबों:


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

या

sv.scrollTo(5, 10);


43
Ercu के उत्तर और उस पर की गई टिप्पणी को मिलाकर, सबसे अच्छा तरीका प्रतीत होता है:mScrollView.post(new Runnable() { public void run() { mScrollView.fullScroll(View.FOCUS_DOWN); } });
गौरैया

2
स्क्रॉलोटो () इच्छा पुनर्विक्रय का उत्पादन नहीं करेगा। फुलसक्रोल () के साथ जाना चाहिए
अमित यादव

3
अधिक अच्छा स्क्रॉल प्राकृतिक प्रभाव के साथ है: sv.smoothScrollTo (5, 10)
ivan.panasiuk

205

प्रज्ञा का जवाब हमेशा काम नहीं करता है, यह कोशिश करें:

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

या

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

यदि आप शुरू करने के लिए स्क्रॉल करना चाहते हैं

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

28
मैंने mScrollView.fullScroll(mScrollView.FOCUS_DOWN);सफलता के साथ प्रयोग किया ।
AMCC

3
मैं वैंथेल के निष्कर्षों की पुष्टि कर सकता हूं। mScrollView.fullScroll में एक पोस्ट रननेबल ने चाल चली।
एलनक्ले

1
अति उत्कृष्ट ! वास्तव में, Runnable के बिना, यह काम नहीं किया। अब यह काम कर रहा है ! :)
18

5
@HiteshDhamshaniya यदि आप एक चिकनी स्क्रॉल चाहते हैं, तो प्रयास करें mScrollView.smoothScrollTo(0, mScrollView.getBottom());
माइक ऑर्टिज़

1
postयहाँ इसकी आवश्यकता क्यों है?
Liuting

35

मैं स्क्रॉल दृश्य को सीधे onCreateView () के बाद स्क्रॉल करना चाहता था (जैसे एक बटन क्लिक करने के बाद नहीं)। यह काम करने के लिए मुझे एक ViewTreeObserver का उपयोग करने की आवश्यकता है:

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

लेकिन सावधान रहें कि यह कहा जाता है कि हर बार कुछ लेआउट हो जाता है (जैसे कि यदि आप अदृश्य या इसी तरह का कोई दृश्य सेट करते हैं) तो इस श्रोता को हटाना न भूलें अगर आपको इसकी आवश्यकता नहीं है:

public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) एसडीके लवल <16 पर

या

public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) एसडीके लवल में = 16


23

यहां बहुत सारे अच्छे उत्तर हैं, लेकिन मैं केवल एक बात जोड़ना चाहता हूं। यह कभी-कभी ऐसा होता है कि आप अपने स्क्रॉलव्यू को लेआउट के किसी विशिष्ट दृश्य पर स्क्रॉल करना चाहते हैं, बजाय ऊपर या नीचे एक पूर्ण स्क्रॉल के।

एक सरल उदाहरण: एक पंजीकरण फॉर्म में, यदि उपयोगकर्ता प्रपत्र के एक संपादित पाठ को नहीं भर पाने पर "साइनअप" बटन पर टैप करता है, तो आप उपयोगकर्ता को यह बताने के लिए उस विशिष्ट संपादन पाठ पर स्क्रॉल करना चाहते हैं कि उसे उस फ़ील्ड को भरना होगा।

उस मामले में, आप ऐसा कुछ कर सकते हैं:

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

या, यदि आप एक त्वरित स्क्रॉल के बजाय एक चिकनी स्क्रॉल चाहते हैं:

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

जाहिर है आप एडिट टेक्स्ट के बजाय किसी भी प्रकार के दृश्य का उपयोग कर सकते हैं। ध्यान दें कि getBottom () अपने पैरेंट लेआउट के आधार पर दृश्य के निर्देशांक लौटाता है, इसलिए स्क्रॉल दृश्य के अंदर उपयोग किए जाने वाले सभी दृश्यों में केवल एक माता-पिता (उदाहरण के लिए एक रैखिक लेआउट) होना चाहिए।

यदि आपके पास स्क्रॉलव्यू के बच्चे के अंदर कई माता-पिता हैं, तो मुझे जो एकमात्र समाधान मिला है, वह है माता-पिता को अनुरोध पर कॉल करें:

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

लेकिन इस मामले में आप एक चिकनी स्क्रॉल नहीं कर सकते।

मुझे उम्मीद है कि यह उत्तर किसी को उसी समस्या से मदद कर सकता है।


1
@JohnT खुशी है कि यह आप में मदद की :)
मेटिया रगइएरो



8

यदि आप तुरंत स्क्रॉल करना चाहते हैं तो आप उपयोग कर सकते हैं:

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

या यदि आप आसानी से और धीरे-धीरे स्क्रॉल करना चाहते हैं तो आप इसका उपयोग कर सकते हैं:

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

वह catchब्लॉक क्या करता है ?
जॉन सरदिन्हा

1
कैच ब्लॉक स्क्रॉल के दौरान अपवादों को पकड़ना है यदि कोई पाया गया।
मैडी

5

** वांछित ऊंचाई तक स्क्रॉल करने के लिए। मैं कुछ अच्छे समाधान के साथ आया हूँ **

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

4

मुझे यह स्क्रॉल स्क्रॉल के नीचे स्क्रॉल करने के लिए काम करने के लिए मिला (अंदर एक टेक्स्ट दृश्य के साथ):

(मैंने इसे TextView को अपडेट करने वाली विधि पर रखा)

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

4

हाँ तुम कर सकते हो।

मान लीजिए कि आपको एक मिल गया है Layoutऔर उसके अंदर, आपको कई मिल गए हैं Views। इसलिए यदि आप किसी भी Viewप्रोग्राम को स्क्रॉल करना चाहते हैं , तो आपको निम्नलिखित कोड स्निपेट लिखना होगा:

उदाहरण के लिए:

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

यदि आप किसी विशेष पर स्क्रॉल करना चाहते हैं View, तो बताएं कि इस मामले में, केवल लिखें:

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

और आप कर रहे हैं।


3

नोट: यदि आप पहले से ही एक थ्रेड में हैं, तो आपको एक नया पोस्ट थ्रेड बनाना होगा, या यह पूर्ण अंत तक (मेरे लिए) तक नई लंबी ऊंचाई स्क्रॉल नहीं करेगा। पूर्व के लिए:

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

एक और उत्तर जोड़ना जिसमें निर्देशांक शामिल नहीं है।

यह आपके इच्छित दृश्य को फ़ोकस करने के लिए लाएगा (लेकिन शीर्ष स्थान पर नहीं):

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

सार्वजनिक शून्य RequestChildFocus (बच्चे को देखें, ध्यान केंद्रित देखें)

बच्चा - इस ViewParent का बच्चा जो फोकस चाहता है। इस दृश्य में केंद्रित दृश्य होगा। जरूरी नहीं कि वह नजरिया वास्तव में फोकस हो।

ध्यान केंद्रित - वह दृश्य जो बच्चे का वंशज है जो वास्तव में ध्यान केंद्रित करता है


वास्तव में मुझे क्या चाहिए, धन्यवाद। आपके लिए स्क्रॉल अनुरोध देखने के लिए पहले अनुरोध करें और फिर स्क्रॉल करें ।smoothScrollTo (0, scrollView.getChildAt (0) .getBottom ());
वुलोविक वुकसिन


2

हर कोई ऐसे जटिल जवाब पोस्ट कर रहा है।

मुझे एक आसान जवाब मिला, नीचे की ओर स्क्रॉल करने के लिए, अच्छी तरह से:

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

और, यदि आवश्यक हो, तो आप कोड की दूसरी पंक्ति को ऊपर, एक चलाने योग्य में डाल सकते हैं:

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

इस सरल समाधान को खोजने के लिए मुझे बहुत अधिक शोध और खेल करना पड़ा। मुझे आशा है कि यह आपकी मदद भी करेगा! :)


1

मैं sv.fullScroll (View.FOCUS_DOWN) के साथ रननेबल का उपयोग कर रहा था; यह तत्काल समस्या के लिए पूरी तरह से काम करता है, लेकिन यह तरीका स्क्रॉल स्क्रीन को पूरी स्क्रीन से फोकस करता है, यदि आप हर बार ऐसा करने के लिए AutoScroll करते हैं, तो कोई भी EditText उपयोगकर्ता से जानकारी प्राप्त करने में सक्षम नहीं होगा, मेरा समाधान एक अलग कोड का उपयोग करता था चलने योग्य:

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

महत्वपूर्ण विचारों पर ध्यान केंद्रित किए बिना समान बनाना

अभिवादन।


0

यह मेरे लिए काम कर रहा है

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

        }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.