স্ক্রোলভিউয়ের জন্য আমার কী অনস্ক্রোললিস্টার থাকতে পারে?


140

আমি HorizontalScrollViewএকটি বিন্যাসে একটি ব্যবহার করছি এবং আমাকে চিহ্নিত করতে হবে যে ব্যবহারকারীটি স্ক্রোলটির শুরু এবং শেষের পয়েন্টে পৌঁছেছে।

যেহেতু ListViewআমি চেষ্টা করেছি onScrollListenerএবং স্ক্রোলের শুরু এবং শেষের পয়েন্টটি পাওয়া সম্ভব।

আমি আমার মধ্যেও এটি করার চেষ্টা করেছি Scrollviewতবে মনে হচ্ছে এটি সম্ভব নয়। আমার যা প্রয়োজন তা অর্জনের জন্য অন্য কোনও সম্ভাব্য উপায় আছে কি?


3
এটা সম্ভব. ব্যবহারকারী 2695685 এর উত্তর দেখুন। সংক্ষেপে নিম্নলিখিতটি onStartকৌতুকটি করবে: hsv.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {@Override public void onScrollChanged() {Log.i(TAG,"scroll:"+hsv.getScrollX());}});অনস্টার্টে () যেখানে hsvকোনও HorizontalScrollViewকাজ রয়েছে।
জনিলম্বদা

যে কোনও দরকারী উত্তর গ্রহণ করুন .. অন্যথায় নিজের উত্তর পোস্ট করুন ..
রণজিৎ কুমার

12
অ্যান্ড্রয়েডে স্ক্রোলভিউয়ের সাথে কোনও স্ক্রোল ইভেন্ট সনাক্ত করা কেন এত কঠিন? এটি বাদাম ইমো।
কাজ করেছে

উত্তর:


389

ভিউ কলগুলির প্রতিটি উদাহরণ getViewTreeObserver()। এখন কোনও উদাহরণ ধারণ করার সময় ViewTreeObserverআপনি OnScrollChangedListener()পদ্ধতিটি ব্যবহার করে এটিতে একটি যুক্ত করতে পারেন addOnScrollChangedListener()

আপনি এই শ্রেণীর সম্পর্কে আরও তথ্য এখানে দেখতে পারেন ।

এটি আপনাকে প্রতিটি স্ক্রোলিং ইভেন্ট সম্পর্কে সচেতন হতে দেয় - তবে সমন্বয় ছাড়াই। আপনি এগুলি ব্যবহার করে getScrollY()বা getScrollX()শ্রোতার মধ্যে থেকে তবে তা পেতে পারেন ।

scrollView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {
    @Override
    public void onScrollChanged() {
        int scrollY = rootScrollView.getScrollY(); // For ScrollView
        int scrollX = rootScrollView.getScrollX(); // For HorizontalScrollView
        // DO SOMETHING WITH THE SCROLL COORDINATES
    }
});

6
এই উত্তরটি সঠিক হিসাবে চিহ্নিত করা উচিত। hsv.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {@Override public void onScrollChanged() {Log.i(TAG,"scroll:"+hsv.getScrollX());}});onStart মধ্যে () যেখানে hsvএকটি হল HorizontalScrollViewকাজ করে। আমার সন্দেহ হয় একই স্ক্রোলভিউয়ের জন্যও কাজ করবে।
জনিলম্বদা

3
ঠিক। এটি সেরা উত্তর। হরিজন্টসক্রোলভিউ বাড়ানোর দরকার নেই। একটি স্ক্রোলভিউ দিয়ে সবেমাত্র পরীক্ষিত, দুর্দান্ত কাজ করেছে: চূড়ান্ত স্ক্রোলভিউ এসভি = (স্ক্রোলভিউ) সন্ধান ভিউবিআইডি (আর.আইডি.স্ক্রোলভিউআর্টিকাল); sv.getViewTreeObserver ()। addOnScrolChangedListener (new ViewTreeObserver.OnScrolChangedListener () {@ ওভাররাইড পাবলিক শূন্যপরিবর্তিত স্ক্রোলচেন্জড ()। লগ.ড ("oncrolChanged Y", স্ট্রিং.ভ্যালুঅফ))
রাফেল সি


6
উত্তরের নমুনা কোড একটি মেমরি ফাঁস প্রবর্তন করে। যেহেতু পদ্ধতিটি addনা এবং তাই নয় set, সমস্ত শ্রোতা স্পষ্টভাবে অপসারণ না করা অবধি রক্ষণাবেক্ষণ করা হবে। সুতরাং নমুনায় শ্রোতা বাস্তবায়ন হিসাবে ব্যবহৃত বেনাম শ্রেণি ফাঁস হবে (এটি উল্লেখযোগ্য কোনও কিছু সহ, যেমন বাইরের শ্রেণি)।
ব্রেট ডানক্যাভেজ

7
সম্ভবত একটি বোবা প্রশ্ন, কিন্তু রুটস্ক্রোলভিউ কী?
ইকবাল

49

এটি খুব দরকারী হতে পারে। NestedScrollViewপরিবর্তে ব্যবহার করুন ScrollView। সাপোর্ট লাইব্রেরি 23.1 একটি চালুOnScrollChangeListener করার NestedScrollView। সুতরাং আপনি এই মত কিছু করতে পারেন।

 myScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
            //Do something
        }
    });

2
আপনি আগে ভিটভিট্রিঅবার্সার () দিয়ে শ্রোতাদের যোগ করেছেন কিনা তা ট্র্যাক করে রাখার চেয়ে অবশ্যই সহজ। ধন্যবাদ!
অ্যান্টনি মিলস

তবে কীভাবে নেস্টডস্ক্রোলভিউ অনুভূমিক স্ক্রোল ভিউ হিসাবে ব্যবহার করবেন? কোনও সংস্থান খুঁজে পাওয়া যায় না
গেঞ্জা গেমস

আমি যদি অনুভূমিক স্ক্রোলটি ব্যবহার করতে চাই?
নিকিতা অ্যাক্সিওনভ

7
@ dazed'n'confused NestedScrollViewসমর্থন লাইব্রেরির অংশ, এর setOnScrollChangeListenerপদ্ধতির কোনও ন্যূনতম সংস্করণের প্রয়োজন নেই।
টম

4
সঙ্গে গুলিয়ে ফেলা যাবে না View'এর setOnScrollChangeListenerকোন API স্তর 23 প্রয়োজন
অ্যান্ডার্স Ullnæss

18

স্ক্রোলিং এবং স্ক্রোল সমাপ্তি সম্পর্কে বিজ্ঞপ্তিগুলি হ্যান্ডেল করার জন্য আমি এখানে একটি উত্পন্ন হরিজন্টসক্রোলভিউ লিখেছি। এটি সঠিকভাবে পরিচালনা করে যখন কোনও ব্যবহারকারী সক্রিয়ভাবে স্ক্রোলিং বন্ধ করে দেয় এবং যখন কোনও ব্যবহারকারী যেতে দেওয়ার পরে এটি পুরোপুরি হ্রাস পায়:

public class ObservableHorizontalScrollView extends HorizontalScrollView {
    public interface OnScrollListener {
        public void onScrollChanged(ObservableHorizontalScrollView scrollView, int x, int y, int oldX, int oldY);
        public void onEndScroll(ObservableHorizontalScrollView scrollView);
    }

    private boolean mIsScrolling;
    private boolean mIsTouching;
    private Runnable mScrollingRunnable;
    private OnScrollListener mOnScrollListener;

    public ObservableHorizontalScrollView(Context context) {
        this(context, null, 0);
    }

    public ObservableHorizontalScrollView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();

        if (action == MotionEvent.ACTION_MOVE) {
            mIsTouching = true;
            mIsScrolling = true;
        } else if (action == MotionEvent.ACTION_UP) {
            if (mIsTouching && !mIsScrolling) {
                if (mOnScrollListener != null) {
                    mOnScrollListener.onEndScroll(this);
                }
            }

            mIsTouching = false;
        }

        return super.onTouchEvent(ev);
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldX, int oldY) {
        super.onScrollChanged(x, y, oldX, oldY);

        if (Math.abs(oldX - x) > 0) {
            if (mScrollingRunnable != null) {
                removeCallbacks(mScrollingRunnable);
            }

            mScrollingRunnable = new Runnable() {
                public void run() {
                    if (mIsScrolling && !mIsTouching) {
                        if (mOnScrollListener != null) {
                            mOnScrollListener.onEndScroll(ObservableHorizontalScrollView.this);
                        }
                    }

                    mIsScrolling = false;
                    mScrollingRunnable = null;
                }
            };

            postDelayed(mScrollingRunnable, 200);
        }

        if (mOnScrollListener != null) {
            mOnScrollListener.onScrollChanged(this, x, y, oldX, oldY);
        }
    }

    public OnScrollListener getOnScrollListener() {
        return mOnScrollListener;
    }

    public void setOnScrollListener(OnScrollListener mOnEndScrollListener) {
        this.mOnScrollListener = mOnEndScrollListener;
    }

}

1
দেখে মনে হচ্ছে ভিউটি ট্রিউবার্সার পদ্ধতিটি ব্যবহার করার চেয়ে এটি ভাল। কেবলমাত্র যখন আপনার কোনও ক্রিয়াকলাপ থাকে যেখানে আপনার একাধিক টুকরো লোড থাকে (উদাহরণস্বরূপ স্লাইডিং ট্যাব সহ 3 টুকরা) তালিকাভিউ এবং স্ক্রোলভিউ সহ এবং আপনাকে নির্দিষ্ট দৃষ্টির জন্য ইভেন্টগুলি নিবন্ধভুক্ত করতে হবে। যদিও ভিউটি ট্রিউজারবারটি নিবন্ধিত থাকলে এটি সক্রিয় দৃষ্টিতে না থাকলেও ইভেন্টগুলিকে আগুন ধরিয়ে দেবে।
টর্স্টেন ওজাপার্ভ

3
@ জাব্ল্যাঙ্ক - আপনি কীভাবে আমাকে এই ক্লাসটি এবং আমার কার্যকলাপ থেকে শ্রোতাদের স্ক্রোলভিউ ধারণ করে কীভাবে সূচনা করতে পারেন তা আমাকে জানান? আমি এটি ঠিকঠাক প্রয়োগ করেছি, তবে শ্রোতা এখনও কোনও মান ফিরিয়ে দেবে না।
এডমন্ড তমাস

এটি আসলে কাজ করে! এবং এর জন্য এসডিকে> 23 এর দরকার নেই :)
মাতান দহন

5

যদি আপনি কোনও দৃশ্যের স্ক্রোল অবস্থানটি জানতে চান, তবে আপনি দেখুন শ্রেণিতে নিম্নলিখিত এক্সটেনশন ফাংশনটি ব্যবহার করতে পারেন:

fun View?.onScroll(callback: (x: Int, y: Int) -> Unit) {
    var oldX = 0
    var oldY = 0
    this?.viewTreeObserver?.addOnScrollChangedListener {
        if (oldX != scrollX || oldY != scrollY) {
            callback(scrollX, scrollY)
            oldX = scrollX
            oldY = scrollY
        }
    }
}

5

আপনি NestedScrollViewপরিবর্তে ব্যবহার করতে পারেন ScrollView। যাইহোক, কোটলিন ল্যাম্বদা ব্যবহার করার সময় এটি জানতে পারবেন না যে আপনি setOnScrollChangeListenerভিউতে (যা এপিআই স্তর 23) এর পরিবর্তে নেস্টেডস্ক্রোলভিউ চান । নেস্টডস্ক্রোলভিউ হিসাবে প্রথম প্যারামিটার নির্দিষ্ট করে আপনি এটি ঠিক করতে পারেন।

nestedScrollView.setOnScrollChangeListener { _: NestedScrollView, scrollX: Int, scrollY: Int, _: Int, _: Int ->
    Log.d("ScrollView", "Scrolled to $scrollX, $scrollY")
}

এটি গ্রহণযোগ্য উত্তর হওয়া উচিত কারণ ভিউটি ট্রিউবার্সার ব্যবহারের পদ্ধতিটির ফলে মেমরি ফাঁস হয় এবং অবশ্যই ম্যানুয়ালি অপসারণ করা উচিত অন্যথায় একাধিক স্ক্রোল পর্যবেক্ষক যুক্ত করা হবে।
রে লি

1
    // --------Start Scroll Bar Slide--------
    final HorizontalScrollView xHorizontalScrollViewHeader = (HorizontalScrollView) findViewById(R.id.HorizontalScrollViewHeader);
    final HorizontalScrollView xHorizontalScrollViewData = (HorizontalScrollView) findViewById(R.id.HorizontalScrollViewData);
    xHorizontalScrollViewData.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            int scrollX; int scrollY;
            scrollX=xHorizontalScrollViewData.getScrollX();
            scrollY=xHorizontalScrollViewData.getScrollY();
            xHorizontalScrollViewHeader.scrollTo(scrollX, scrollY);
        }
    });
    // ---------End Scroll Bar Slide---------

আপনার কোডটি সমর্থন করার জন্য দয়া করে কিছু বিবরণ যুক্ত করার চেষ্টা করুন যা সবাইকে বুঝতে সাহায্য করবে
অনিরুদ্ধ দাস

এই কোডটি অন্য উত্তরের সাথে খুব মিল , তাই না?
সের্গেই

1

আপনি একটি কাস্টম স্ক্রোলভিউ ক্লাস সংজ্ঞায়িত করতে পারেন, এবং এই জাতীয় স্ক্রোল করার সময় কল করা একটি ইন্টারফেস যুক্ত করুন:

public class ScrollChangeListenerScrollView extends HorizontalScrollView {


private MyScrollListener mMyScrollListener;

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

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

public ScrollChangeListenerScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}


public void setOnMyScrollListener(MyScrollListener myScrollListener){
    this.mMyScrollListener = myScrollListener;
}


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

}

public interface MyScrollListener {
    void onScrollChange(View view,int scrollX,int scrollY,int oldScrollX, int oldScrollY);
}

}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.