android software - एंड्रॉइड में Viewpager नियंत्रक की धीमी गति




5 Answers

मैंने हाईफ्लियर कोड के साथ शुरुआत की है जो वास्तव में एमएसक्रॉलर फ़ील्ड को बदलता है (जो एक महान शुरुआत है) लेकिन स्क्रॉल की अवधि बढ़ाने में मदद नहीं की क्योंकि स्क्रॉल करने का अनुरोध करते समय ViewPager एमएसक्रॉलर को अवधि को स्पष्ट रूप से पास करता है।

व्यूपेजर विस्तार करना महत्वपूर्ण तरीका नहीं है (smoothScrollTo) ओवरराइड नहीं किया जा सकता है।

मैंने इस कोड के साथ स्क्रॉलर को विस्तारित करके इसे ठीक कर दिया:

public class FixedSpeedScroller extends Scroller {

    private int mDuration = 5000;

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

    public FixedSpeedScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }

    public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) {
        super(context, interpolator, flywheel);
    }


    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }
}

और इसका उपयोग इस तरह करते हैं:

try {
    Field mScroller;
    mScroller = ViewPager.class.getDeclaredField("mScroller");
    mScroller.setAccessible(true); 
    FixedSpeedScroller scroller = new FixedSpeedScroller(mPager.getContext(), sInterpolator);
    // scroller.setFixedDuration(5000);
    mScroller.set(mPager, scroller);
} catch (NoSuchFieldException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}

मैंने मूल रूप से 5 सेकंड तक अवधि को हार्डकोड किया है और मेरा व्यूपार्जर इसका उपयोग किया है।

उम्मीद है की यह मदद करेगा।

download in

एंड्रॉइड में व्यूपेजर एडेप्टर के साथ स्क्रॉल स्पीड को धीमा करने का कोई तरीका है?

आप जानते हैं, मैं इस कोड को देख रहा हूं। मैं यह नहीं समझ सकता कि मैं क्या गलत हूं।

try{ 
    Field mScroller = mPager.getClass().getDeclaredField("mScroller"); 
    mScroller.setAccessible(true); 
    Scroller scroll = new Scroller(cxt);
    Field scrollDuration = scroll.getClass().getDeclaredField("mDuration");
    scrollDuration.setAccessible(true);
    scrollDuration.set(scroll, 1000);
    mScroller.set(mPager, scroll);
}catch (Exception e){
    Toast.makeText(cxt, "something happened", Toast.LENGTH_LONG).show();
} 

यह कुछ भी नहीं बदलता है अभी तक कोई अपवाद नहीं होता है?




मुझे @ df778899 के उत्तर और एंड्रॉइड वैल्यूएनिमीटर एपीआई के आधार पर बेहतर समाधान मिला है । यह प्रतिबिंब के बिना ठीक काम करता है और बहुत लचीला है। कस्टम व्यूपैगर बनाने और इसे android.support.v4.view पैकेज में डालने की कोई आवश्यकता नहीं है। यहाँ एक उदाहरण है:

private void animatePagerTransition(final boolean forward) {

    ValueAnimator animator = ValueAnimator.ofInt(0, viewPager.getWidth() - ( forward ? viewPager.getPaddingLeft() : viewPager.getPaddingRight() ));
    animator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            viewPager.endFakeDrag();
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            viewPager.endFakeDrag();
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    });

    animator.setInterpolator(new AccelerateInterpolator());
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

        private int oldDragPosition = 0;

        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            int dragPosition = (Integer) animation.getAnimatedValue();
            int dragOffset = dragPosition - oldDragPosition;
            oldDragPosition = dragPosition;
            viewPager.fakeDragBy(dragOffset * (forward ? -1 : 1));
        }
    });

    animator.setDuration(AppConstants.PAGER_TRANSITION_DURATION_MS);
    viewPager.beginFakeDrag();
    animator.start();
}



जैसा कि आप ViewPager स्रोतों में see सकते see , mscroller ऑब्जेक्ट द्वारा नियंत्रित फ़्लिंग की अवधि। documantation हम पढ़ सकते हैं:

स्क्रॉल की अवधि कन्स्ट्रक्टर में पारित की जा सकती है और स्क्रॉलिंग एनीमेशन लेने वाले अधिकतम समय को निर्दिष्ट करता है

इसलिए, यदि आप गति को नियंत्रित करना चाहते हैं, तो आप प्रतिबिंब के माध्यम से mScroller ऑब्जेक्ट बदल सकते हैं।

आपको ऐसा कुछ लिखना चाहिए:

setContentView(R.layout.main);
mPager = (ViewPager)findViewById(R.id.view_pager);
Field mScroller = ViewPager.class.getDeclaredField("mScroller");   
mScroller.setAccessible(true);
mScroller.set(mPager, scroller); // initialize scroller object by yourself 



मैंने उपयोग कर लिया है

DecelerateInterpolator ()

उदाहरण यहां दिया गया है:

  mViewPager = (ViewPager) findViewById(R.id.container);
            mViewPager.setAdapter(mSectionsPagerAdapter);
            Field mScroller = null;
            try {
                mScroller = ViewPager.class.getDeclaredField("mScroller");
                mScroller.setAccessible(true);
                Scroller scroller = new Scroller(this, new DecelerateInterpolator());
                mScroller.set(mViewPager, scroller);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }



                binding.vpTour.beginFakeDrag();
                lastFakeDrag = 0;
                ValueAnimator va = ValueAnimator.ofInt(0, binding.vpTour.getWidth());
                va.setDuration(1000);
                va.addUpdateListener(animation -> {
                    if (binding.vpTour.isFakeDragging()) {
                        int animProgress = (Integer) animation.getAnimatedValue();
                        binding.vpTour.fakeDragBy(lastFakeDrag - animProgress);
                        lastFakeDrag = animProgress;
                    }
                });
                va.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        if (binding.vpTour.isFakeDragging()) {
                            binding.vpTour.endFakeDrag();
                        }
                    }
                });
                va.start();

मैं आप सभी के समान मुद्दे को हल करना चाहता था और यह एक ही समस्या के लिए मेरा समाधान है, लेकिन मुझे लगता है कि इस तरह समाधान समाधान अधिक लचीला है क्योंकि आप अवधि को बदल सकते हैं, हालांकि आप चाहें वांछित मूल्यों के इंटरपोलेशन को भी बदल सकते हैं विभिन्न दृश्य प्रभाव प्राप्त करने के लिए। मेरा समाधान पृष्ठ "1" से पृष्ठ "2" में स्वाइप करता है, इसलिए केवल बढ़ती स्थितियों में, लेकिन "lastFakeDrag - animProgress" के बजाय "animProgress - lastFakeDrag" करके कम स्थिति में जाने के लिए आसानी से बदला जा सकता है। मुझे लगता है कि यह कार्य करने के लिए यह सबसे लचीला समाधान है।




Related


Tags

android