ความเร็วที่ช้าลงของคอนโทรลเลอร์ Viewpager ใน Android


105

มีวิธีใดบ้างที่จะทำให้ความเร็วในการเลื่อนช้าลงด้วยอะแดปเตอร์ viewpager ใน Android


คุณรู้ไหมฉันกำลังดูรหัสนี้ ฉันคิดไม่ออกว่าฉันผิดอะไร

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

มันไม่เปลี่ยนแปลงอะไรเลยยังไม่มีข้อยกเว้นเกิดขึ้น?



1
child.setNestedScrollingEnabled(false);ทำงานให้ฉัน
ปิแอร์

คำตอบ:


230

ฉันเริ่มต้นด้วยรหัส HighFlyer ซึ่งเปลี่ยนฟิลด์ mScroller (ซึ่งเป็นการเริ่มต้นที่ดี) แต่ไม่ได้ช่วยขยายระยะเวลาของการเลื่อนเนื่องจาก ViewPager ส่งระยะเวลาไปยัง mScroller อย่างชัดเจนเมื่อขอเลื่อน

การขยาย ViewPager ไม่ทำงานเนื่องจากวิธีการสำคัญ (smoothScrollTo) ไม่สามารถแทนที่ได้

ฉันลงเอยด้วยการแก้ไขสิ่งนี้โดยการขยาย Scroller ด้วยรหัสนี้:

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 วินาทีและทำให้ ViewPager ของฉันใช้งานได้

หวังว่านี่จะช่วยได้


16
ช่วยบอกหน่อยได้ไหมว่า sInterpolator คืออะไร ??
Shashank Degloorkar

10
'Interpolator' คืออัตราการทำงานของภาพเคลื่อนไหวเช่นสามารถเร่งความเร็วลดความเร็วและอื่น ๆ อีกมากมาย มีตัวสร้างที่ไม่มีอินเทอร์โพลเตอร์ฉันคิดว่ามันน่าจะใช้ได้ดังนั้นเพียงแค่พยายามลบอาร์กิวเมนต์นั้นออกจากการโทร หากไม่ได้ผลให้เพิ่ม: 'Interpolator sInterpolator = new AccelerateInterpolator ()'
marmor

8
ฉันพบว่า DecelerateInterpolator ทำงานได้ดีขึ้นในกรณีนี้มันจะรักษาความเร็วของการปัดครั้งแรกแล้วค่อยๆลดลง
Quint Stoffers

สวัสดีคุณมีความคิดว่าเหตุใดจึงscroller.setFixedDuration(5000);ให้ข้อผิดพลาด มันบอกว่า "The method setFixedDuration (int) is undefined"
jaibatrik

6
หากคุณใช้ proguard อย่าลืมเพิ่มบรรทัดนี้: -keep class android.support.v4 ** {*;} มิฉะนั้นคุณจะได้รับตัวชี้ null เมื่อ getDeclaredField ()
GuilhE

61

ฉันอยากทำอะไรด้วยตัวเองและประสบความสำเร็จในการแก้ปัญหา คล้ายกับโซลูชันที่ยอมรับ แต่ใช้ interpolator เดียวกันและเปลี่ยนระยะเวลาตามปัจจัยเท่านั้น คุณต้องใช้ a ViewPagerCustomDurationใน XML ของคุณแทนจากViewPagerนั้นคุณสามารถทำได้:

ViewPagerCustomDuration vp = (ViewPagerCustomDuration) findViewById(R.id.myPager);
vp.setScrollDurationFactor(2); // make the animation twice as slow

ViewPagerCustomDuration.java:

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.animation.Interpolator;

import java.lang.reflect.Field;

public class ViewPagerCustomDuration extends ViewPager {

    public ViewPagerCustomDuration(Context context) {
        super(context);
        postInitViewPager();
    }

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

    private ScrollerCustomDuration mScroller = null;

    /**
     * Override the Scroller instance with our own class so we can change the
     * duration
     */
    private void postInitViewPager() {
        try {
            Class<?> viewpager = ViewPager.class;
            Field scroller = viewpager.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            Field interpolator = viewpager.getDeclaredField("sInterpolator");
            interpolator.setAccessible(true);

            mScroller = new ScrollerCustomDuration(getContext(),
                    (Interpolator) interpolator.get(null));
            scroller.set(this, mScroller);
        } catch (Exception e) {
        }
    }

    /**
     * Set the factor by which the duration will change
     */
    public void setScrollDurationFactor(double scrollFactor) {
        mScroller.setScrollDurationFactor(scrollFactor);
    }

}

ScrollerCustomDuration.java:

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.animation.Interpolator;
import android.widget.Scroller;

public class ScrollerCustomDuration extends Scroller {

    private double mScrollFactor = 1;

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

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

    @SuppressLint("NewApi")
    public ScrollerCustomDuration(Context context, Interpolator interpolator, boolean flywheel) {
        super(context, interpolator, flywheel);
    }

    /**
     * Set the factor by which the duration will change
     */
    public void setScrollDurationFactor(double scrollFactor) {
        mScrollFactor = scrollFactor;
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        super.startScroll(startX, startY, dx, dy, (int) (duration * mScrollFactor));
    }

}

หวังว่านี่จะช่วยใครสักคน!


3
ฉันชอบโซลูชันนี้ดีกว่าคำตอบที่ยอมรับเนื่องจาก ViewPager ที่กำหนดเองเป็นคลาสดรอปอินที่มีการเปลี่ยนแปลงโค้ดที่มีอยู่เพียงเล็กน้อย การมี scroller ที่กำหนดเองเป็นคลาสภายในแบบคงที่ของ ViewPager ที่กำหนดเองทำให้มีการห่อหุ้มมากยิ่งขึ้น
Emanuel Moecklin

1
หากคุณใช้ proguard อย่าลืมเพิ่มบรรทัดนี้: -keep class android.support.v4 ** {*;} มิฉะนั้นคุณจะได้รับตัวชี้ null เมื่อ getDeclaredField ()
GuilhE

ฉันขอแนะนำให้อัปเดตเป็น ternary เนื่องจากคุณไม่ต้องการให้ใครผ่านด้วยปัจจัย 0 ซึ่งจะทำให้ระยะเวลาของคุณเสียหาย อัพเดตพารามิเตอร์สุดท้ายที่คุณส่งผ่านไปยัง mScrollFactor> 0? (int) (ระยะเวลา * mScrollFactor): ระยะเวลา
portfoliobuilder

ฉันขอแนะนำให้คุณทำการตรวจสอบค่าว่างเมื่อตั้งค่าปัจจัยการเลื่อนในคลาสของคุณ ViewPagerCustomDuration คุณสร้างอินสแตนซ์โดยใช้ mScroller เป็นวัตถุว่างคุณควรยืนยันว่ายังไม่เป็นโมฆะเมื่อพยายามตั้งค่าปัจจัยการเลื่อนบนวัตถุนั้น
portfoliobuilder

@portfoliobuilder ความคิดเห็นที่ถูกต้องแม้ว่าดูเหมือนว่าคุณจะชอบรูปแบบการเขียนโปรแกรมเชิงป้องกันมากกว่าซึ่ง IMO เหมาะกับไลบรารีทึบแสงมากกว่าตัวอย่างข้อมูลบน SO การตั้งค่าปัจจัยการเลื่อนเป็น <= 0 เช่นเดียวกับการเรียก setScrollDurationFactor ในมุมมองที่ไม่สร้างอินสแตนซ์เป็นสิ่งที่นักพัฒนา Android ส่วนใหญ่ควรหลีกเลี่ยงการทำโดยไม่ต้องตรวจสอบรันไทม์
Oleg Vaskevich

43

ฉันได้พบทางออกที่ดีกว่าขึ้นอยู่กับคำตอบ @ df778899 ของและ Android ValueAnimator API ทำงานได้ดีโดยไม่มีการสะท้อนและมีความยืดหยุ่นมาก นอกจากนี้ไม่จำเป็นต้องสร้าง ViewPager แบบกำหนดเองและใส่ลงในแพ็คเกจ 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();
}

7
ฉันคิดว่านี่เป็นการประเมินราคาต่ำ มันใช้ประโยชน์startFakeDragและendFakeDragมีไว้เพื่อทำมากกว่าที่มีอยู่ในViewPagerกล่อง สิ่งนี้ใช้งานได้ดีสำหรับฉันและเป็นสิ่งที่ฉันกำลังมองหา
user3280133

1
นั่นเป็นทางออกที่ดีขอบคุณ การเพิ่มประสิทธิภาพเล็ก ๆ อย่างหนึ่ง: เพื่อให้สามารถทำงานกับ viewPager ที่มีช่องว่างภายในบรรทัดแรกควรเป็น ... ValueAnimator.ofInt (0, viewPager.getWidth () - (forward? viewPager.getPaddingLeft (): viewPager.getPaddingRight () ));
DmitryO.

1
นี่เป็นวิธีแก้ปัญหาที่ง่ายที่สุด / มีประสิทธิภาพ / รับผิดเนื่องจากไม่คำนึงถึงการสะท้อนและหลีกเลี่ยงการละเมิดการปิดผนึกเช่นเดียวกับโซลูชันข้างต้น
Ryhan

2
@lobzic คุณเรียกanimatePagerTransition(final boolean forwardวิธีการของคุณว่าอย่างไร? นั่นคือสิ่งที่ฉันสับสน คุณเรียกมันด้วยViewPager.OnPageChangeListenerวิธีการเชื่อมต่อแบบใดแบบหนึ่งหรือไม่? หรือที่อื่น?
Sakiboy

ไม่มีแฮ็กสะท้อนที่น่าเกลียด กำหนดค่าได้อย่างง่ายดาย คำตอบที่ดีมาก
Oren

18

ดังที่คุณเห็นในแหล่งที่มาของ ViewPager ระยะเวลาของการพุ่งควบคุมโดยวัตถุ mScroller ในเอกสารเราอาจอ่าน:

ระยะเวลาของการเลื่อนสามารถส่งผ่านในตัวสร้างและระบุเวลาสูงสุดที่ควรใช้ในการเลื่อนภาพเคลื่อนไหว

ดังนั้นหากคุณต้องการควบคุมความเร็วคุณอาจเปลี่ยนวัตถุ 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 

ฉันสับสนเล็กน้อยเกี่ยวกับวิธีการนี้ - ฉันกำลังตั้งค่า ViewPager ในไฟล์ XML และกำหนดให้กับ mPager และ setAdapter (mAdapter) ... ฉันควรสร้างคลาสที่ขยาย ViewPager หรือไม่
Alex Kelly

12
คุณควรเขียนสิ่งนี้: setContentView (R.layout.main); mPager = (ViewPager) findViewById (R.id.view_pager); ฟิลด์ mScroller = ViewPager.class.getDeclaredField ("mScroller"); mScroller.setAccessible (จริง); mScroller.set (mPager, scroller); // เริ่มต้นวัตถุ scroller ด้วยตัวเอง
HighFlyer

ฉันเพิ่งโพสต์คำตอบอีกหนึ่งคำ ... มันใช้ไม่ได้ ... คุณพอจะมีเวลาให้คำแนะนำบ้างไหมว่าทำไมไม่
Alex Kelly

หลังจากดูแหล่งที่มาอย่างรอบคอบมากขึ้น: ค้นหา mScroller.startScroll (sx, sy, dx, dy); ในแหล่งที่มาของ ViewPager และดูที่ Scroller realization startScroll เรียก startScroll อื่นด้วยพารามิเตอร์ DEFAULT_DURATION มันเป็นไปไม่ได้ที่จะสร้างค่าอื่นสำหรับฟิลด์สุดท้ายแบบคงที่ดังนั้นจึงเหลือโอกาสเดียว - แทนที่ smoothScrollTo ของ ViewPager
HighFlyer

16

นี่ไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์แบบคุณไม่สามารถทำให้ความเร็วช้าลงได้เพราะมันเป็นint. แต่สำหรับฉันมันช้าพอและฉันไม่ต้องใช้การสะท้อน

สังเกตแพคเกจว่าชั้นเรียนอยู่ที่ไหน smoothScrollToมีการมองเห็นแพ็คเกจ

package android.support.v4.view;

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

public class SmoothViewPager extends ViewPager {
    private int mVelocity = 1;

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

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

    @Override
    void smoothScrollTo(int x, int y, int velocity) {
        //ignore passed velocity, use one defined here
        super.smoothScrollTo(x, y, mVelocity);
    }
}

โปรดทราบว่าบรรทัดแรก: "package android.support.v4.view;" เป็นข้อบังคับและคุณควรสร้างแพ็คเกจดังกล่าวที่รูท src ของคุณ หากคุณไม่ทำโค้ดของคุณจะไม่คอมไพล์
Elhanan Mishraky

3
@ElhananMishraky Notice the package where the class isว่านั่นคือสิ่งที่ฉันหมายกับ
pawelzieba

3
รอรอรอ ... wuuuut? คุณสามารถใช้ sdk package-local fields/ methodsหากคุณเพิ่งสร้าง Android Studio คิดว่าคุณใช้แพ็คเกจเดียวกัน? ฉันเป็นคนเดียวที่ได้กลิ่นsealing violationหรือไม่?
Bartek Lipinski

นี่เป็นวิธีแก้ปัญหาที่ดีมาก แต่มันก็ไม่ได้ผลสำหรับฉันทั้งสองอย่างเนื่องจาก Interpolator ที่ ViewPager Scroller ใช้งานไม่ดีในกรณีนี้ ดังนั้นฉันจึงรวมวิธีการแก้ปัญหาของคุณกับคนอื่นโดยใช้การสะท้อนเพื่อรับ mScroller ด้วยวิธีนี้ฉันสามารถใช้ Scroller ดั้งเดิมเมื่อผู้ใช้แบ่งหน้าและ Scroller ที่กำหนดเองของฉันเมื่อฉันเปลี่ยนเพจโดยใช้โปรแกรมด้วย setCurrentItem ()
rolgalan

8

เมธอด fakeDrag บน ViewPager ดูเหมือนจะเป็นทางเลือกอื่น

ตัวอย่างเช่นหน้าจากรายการ 0 ถึง 1:

rootView.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View v) {
      ViewPager pager = (ViewPager) getActivity().findViewById(R.id.pager);
      //pager.setCurrentItem(1, true);
      pager.beginFakeDrag();
      Handler handler = new Handler();
      handler.post(new PageTurner(handler, pager));
  }
});


private static class PageTurner implements Runnable {
  private final Handler handler;
  private final ViewPager pager;
  private int count = 0;

  private PageTurner(Handler handler, ViewPager pager) {
    this.handler = handler;
    this.pager = pager;
  }

  @Override
  public void run() {
    if (pager.isFakeDragging()) {
      if (count < 20) {
        count++;
        pager.fakeDragBy(-count * count);
        handler.postDelayed(this, 20);
      } else {
        pager.endFakeDrag();
      }
    }
  }
}

( count * countมีไว้เพื่อให้การลากเร็วขึ้น)


4

ฉันได้ใช้

ชะลอตัวอินเตอร์โพเลเตอร์ ()

นี่คือตัวอย่าง:

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

2

จากโซลูชันที่ยอมรับฉันได้สร้างคลาส kotlin พร้อมส่วนขยายสำหรับดูเพจเจอร์ สนุก! :)

class ViewPageScroller : Scroller {

    var fixedDuration = 1500 //time to scroll in milliseconds

    constructor(context: Context) : super(context)

    constructor(context: Context, interpolator: Interpolator) : super(context, interpolator)

    constructor(context: Context, interpolator: Interpolator, flywheel: Boolean) : super(context, interpolator, flywheel)


    override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int, duration: Int) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, fixedDuration)
    }

    override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, fixedDuration)
    }
}

fun ViewPager.setViewPageScroller(viewPageScroller: ViewPageScroller) {
    try {
        val mScroller: Field = ViewPager::class.java.getDeclaredField("mScroller")
        mScroller.isAccessible = true
        mScroller.set(this, viewPageScroller)
    } catch (e: NoSuchFieldException) {
    } catch (e: IllegalArgumentException) {
    } catch (e: IllegalAccessException) {
    }

}

1

นี่คือคำตอบโดยใช้วิธีการที่แตกต่างไปจากเดิมอย่างสิ้นเชิง ใครบางคนอาจบอกว่าสิ่งนี้มีความรู้สึกแฮ็ค อย่างไรก็ตามมันไม่ได้ใช้การไตร่ตรองและฉันขอยืนยันว่ามันจะได้ผลเสมอ

เราพบรหัสต่อไปนี้ภายในViewPager.smoothScrollTo:

    if (velocity > 0) {
        duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
    } else {
        final float pageWidth = width * mAdapter.getPageWidth(mCurItem);
        final float pageDelta = (float) Math.abs(dx) / (pageWidth + mPageMargin);
        duration = (int) ((pageDelta + 1) * 100);
    }
    duration = Math.min(duration, MAX_SETTLE_DURATION);

จะคำนวณระยะเวลาตามบางสิ่ง เห็นอะไรที่เราควบคุมได้ไหม? mAdapter.getPageWidth. มาใช้ ViewPager OnPageChangeListener ในอะแดปเตอร์ของเรากัน เรากำลังจะไปตรวจสอบเมื่อ ViewPager ถูกเลื่อนและให้ค่าความกว้างของปลอม ถ้าผมต้องการระยะเวลาที่จะk*100แล้วฉันจะกลับมาสำหรับ1.0/(k-1) getPageWidthต่อไปนี้คือ Kotlin im ของส่วนนี้ของอะแด็ปเตอร์ซึ่งเปลี่ยนระยะเวลาเป็น 400:

    var scrolling = false
    override fun getPageWidth(position: Int): Float {
        return if (scrolling) 0.333f else 1f
    }

    // OnPageChangeListener to detect scroll state
    override fun onPageScrollStateChanged(state: Int) {
        scrolling = state == ViewPager.SCROLL_STATE_SETTLING
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
    }

    override fun onPageSelected(position: Int) {
    }

อย่าลืมเพิ่มอแดปเตอร์เป็น OnPageChangedListener

กรณีเฉพาะของฉันสามารถสันนิษฐานได้อย่างปลอดภัยว่าผู้ใช้ไม่สามารถปัดเพื่อลากระหว่างหน้าได้ หากคุณต้องรองรับการตกตะกอนหลังจากการลากคุณจะต้องทำการคำนวณอีกเล็กน้อย

ข้อเสียอย่างหนึ่งคือขึ้นอยู่กับ100ค่าระยะเวลาพื้นฐานที่ฮาร์ดโค้ดใน ViewPager หากมีการเปลี่ยนแปลงระยะเวลาของคุณจะเปลี่ยนไปตามแนวทางนี้


0
                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" ดังนั้นในตำแหน่งที่เพิ่มขึ้นเท่านั้น แต่สามารถเปลี่ยนเพื่อไปในตำแหน่งที่ลดลงได้อย่างง่ายดายโดยทำ "animProgress - lastFakeDrag" แทน "lastFakeDrag - animProgress" ฉันคิดว่านี่เป็นโซลูชันที่ยืดหยุ่นที่สุดสำหรับการทำงานนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.