स्क्रॉल करें स्क्रॉल स्क्रॉल स्थिति को सिंक्रनाइज़ करें - Android


95

मेरे Android लेआउट में 2 स्क्रॉल दृश्य हैं। मैं उनके स्क्रॉल पदों को कैसे सिंक्रनाइज़ कर सकता हूं?

जवाबों:


289

स्क्रॉलव्यू में एक विधि है ...

protected void onScrollChanged(int x, int y, int oldx, int oldy)

दुर्भाग्य से Google ने कभी नहीं सोचा था कि हमें इसे एक्सेस करने की आवश्यकता होगी, यही वजह है कि उन्होंने इसे संरक्षित किया और "setOnScrollChangedListener" हुक नहीं जोड़ा। इसलिए हमें अपने लिए ऐसा करना होगा।

पहले हमें एक इंटरफ़ेस की आवश्यकता है।

package com.test;

public interface ScrollViewListener {

    void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);

}

फिर हमें स्क्रॉलव्यू क्लास को ओवरराइड करने की आवश्यकता है, स्क्रॉलवैलिस्टनर हुक प्रदान करने के लिए।

package com.test;

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

public class ObservableScrollView extends ScrollView {

    private ScrollViewListener scrollViewListener = null;

    public ObservableScrollView(Context context) {
        super(context);
    }

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

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

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

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        super.onScrollChanged(x, y, oldx, oldy);
        if(scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
        }
    }

}

और हमें वर्तमान स्क्रॉल दृश्य टैग्स के बजाय लेआउट में इस नए ऑब्ज़र्वेबलसर्कल व्यू वर्ग को निर्दिष्ट करना चाहिए।

<com.test.ObservableScrollView
    android:id="@+id/scrollview1"
    ... >

    ...

</com.test.ObservableScrollView>

अंत में, हमने इसे लेआउट क्लास में एक साथ रखा।

package com.test;

import android.app.Activity;
import android.os.Bundle;

public class Q3948934 extends Activity implements ScrollViewListener {

    private ObservableScrollView scrollView1 = null;
    private ObservableScrollView scrollView2 = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.q3948934);

        scrollView1 = (ObservableScrollView) findViewById(R.id.scrollview1);
        scrollView1.setScrollViewListener(this);
        scrollView2 = (ObservableScrollView) findViewById(R.id.scrollview2);
        scrollView2.setScrollViewListener(this);
    }

    public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
        if(scrollView == scrollView1) {
            scrollView2.scrollTo(x, y);
        } else if(scrollView == scrollView2) {
            scrollView1.scrollTo(x, y);
        }
    }

}

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


हाय एंडी इस जवाब को रखने के लिए समय निकालने के लिए धन्यवाद - मुझे आगे बढ़ाया। एक बार फिर धन्यवाद। टिम
टिम

-और मैं भी कोड का उपयोग कर रहा हूं, लेकिन यह मुझे शून्य सूचक फेंक रहा है आप मेरी मदद कर सकते हैं
हेमंत

@ शेमंट क्या आप बता सकते हैं कि NullPointer को किस लाइन में फेंका गया है और आप किस एंड्रॉइड वर्जन के साथ काम कर रहे हैं?
सुलैई

दिन का हीरो: मेरी जान बचा ली! = डी
पेड्रो

हाय एंडी, कोड के लिए धन्यवाद। यह बहुत अच्छा काम करता है। मैं एक बात जानना चाहूंगा [अगर आपके या किसी भी ए 1 के पास है। इसके लिए] - जब मैं अपने स्क्रॉलव्यू को फ्लिंग करता हूं, तो ऑनस्कॉलचेंज विधि, सभी एक्स और वाई को पंजीकृत नहीं करती है जबकि स्क्रॉलव्यू चलता रहता है। यह केवल मुझे शुरुआती स्थिति और अंतिम स्थिति देता है। पूर्व के लिए कहें- मैं Y = 10 से फ़्लिंग शुरू करता हूं और Y = 30 पर छोड़ता हूं और फिर फ़्लिंग वेग इसे Y = 50 पर ले जाता है और फिर रुक जाता है। इसलिए केवल रजिस्टरों को पंजीकृत किया गया है-शायद 10, 11, 12..30 और फिर 49, 50। मैं इसे सभी मध्यवर्ती स्थानों को भी कैसे पंजीकृत कर सकता हूं और 10 से 50 तक सभी निर्देशांक प्राप्त कर सकता हूं ??
कीमियागर

11

एंडी के समाधान में सुधार: अपने कोड में, वह स्क्रोल्टो का उपयोग करता है, मुद्दा यह है, यदि आप एक स्क्रॉलव्यू को एक दिशा में और फिर एक दूसरे को दूसरी दिशा में प्रवाहित कर रहे हैं, तो आप देखेंगे कि पहला व्यक्ति अपने पिछले भाग को नहीं रोकता है आंदोलन।

यह इस तथ्य के कारण है कि यह स्क्रॉल इशारों को करने के लिए स्क्रॉलव्यू computeScroll () का उपयोग करता है, और यह स्क्रॉलोटो के साथ संघर्ष में प्रवेश करता है।

इसे रोकने के लिए, बस इस तरह onScrollChanged प्रोग्राम करें:

    public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
    if(interceptScroll){
        interceptScroll=false;
        if(scrollView == scrollView1) {
            scrollView2.onOverScrolled(x,y,true,true);
        } else if(scrollView == scrollView2) {
            scrollView1.onOverScrolled(x,y,true,true);
        }
        interceptScroll=true;
    }
}

इंटरसेप्टक्रॉल के साथ एक स्थिर बूलियन को सच करने के लिए शुरू किया गया। (यह स्क्रॉलचैन पर अनंत छोरों से बचने में मदद करता है)

onOverScrolled एकमात्र ऐसा फ़ंक्शन है जिसे मैंने पाया कि स्क्रॉलव्यू को फ़्लिंग से रोकने के लिए उपयोग किया जा सकता है (लेकिन कुछ और भी हो सकते हैं जिन्हें मैंने याद किया है!)

इस फ़ंक्शन (जिसे संरक्षित किया गया है) तक पहुंचने के लिए आपको इसे अपने ऑब्जर्वेबलसक्रोल व्यूअर में जोड़ना होगा

public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
}

2
कितनी अच्छी पकड़ है, बेटा!
फ्रांसिस्कोबौजा

5

सिर्फ OnTouchListenerअपनी गतिविधि में ही क्यों नहीं । फिर ऑनटच विधि को ओवरराइड करें, फिर पहले का स्क्रॉल पोस्ट प्राप्त करें ScrollViewOne.getScrollY()और अपडेट करेंScrollViewTwo.scrollTo(0, ScrollViewOne.getScrollY());

बस एक और विचार ... :)


7
यह काम कर सकता है लेकिन जब आप स्पर्श करते हैं और जाने देते हैं तो स्क्रॉल दृश्य आपके द्वारा जाने के बाद थोड़ा और स्क्रॉल कर सकता है जिसे कैप्चर नहीं किया गया है।
अमीर

मैं java में इस मामले में scrollView स्क्रॉल दृश्य का संदर्भ कैसे प्राप्त / प्राप्त कर सकता / सकती हूँ?
बनी खरगोश

स्क्रॉल करने के अन्य तरीके भी हैं (onTrackballEvent () उदाहरण के लिए)
सर्फियाक्लेशिया

यह एक बहुत अच्छा विचार है लेकिन स्क्रॉल वाई स्थिति को प्राप्त करने और स्थापित करने के बजाय, टच इवेंट को दूसरे स्क्रॉलव्यू पर भेजना आसान है। यह "स्क्रॉल" को दूसरे स्क्रॉलव्यू में भी रखेगा। MotionEvent newEvent = MotionEvent.obtain (घटना); documentsScrollView.dispatchTouchEvent (newEvent);
एडुआर्ड मोसिंकॉफ

3

एंड्रॉइड सपोर्ट-वी 4 पैकेज में, एंड्रॉइड नामक एक नया वर्ग प्रदान करता है NestedScrollView

हम <ScrollView>नोड को <android.support.v4.widget.NestedScrollView>लेआउट xml के साथ बदल सकते हैं , और NestedScrollView.OnScrollChangeListenerस्क्रॉलिंग को संभालने के लिए जावा में इसे लागू कर सकते हैं।

इससे चीजें आसान हो जाती हैं।

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