読者です 読者をやめる 読者になる 読者になる

ViewPagerのスクロール速度を変える

f:id:amyu_dev:20140612022524j:plain
溜まってるものを吐き出さねば。
ということで本日2本目

ViewPagerのスクロール速度

ViewPagerのsetCurrentItemを使うとき、引数は(int)か(int, boolean)です。
どちらも第1引数は何ページ目に行くか、第2引数がある方はsmoothScrollがtrue, false的な感じになっています。
で、実際に使ってみると…

まぁ、キモいんです。
キモいというか、早い。
ViewPagerをsetCurrentItemでページ移動した時、左右の移動が早すぎてめくれる感覚というより、Viewが入れ替わってるだけといったような印象を受けます。
そう、Scroll速度が早過ぎるんです。

ということで、タイトル回収。
ViewPagerのScroll速度を変えていきます。

とりあえず、ググる

"android ViewPager setCurrentItem scroll speed"

android - ViewPager setCurrentItem(pageId, true) does NOT smoothscroll - Stack Overflow

はい、こんな感じですね。

で、パk、参考にしながら作ったのがこんな感じですね。

public class CustomViewPager extends ViewPager {

    /**
     * @param context
     */
    public CustomViewPager(Context context) {
        super(context);
        init();
    }

    /**
     * @param context
     * @param attrs
     */
    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     * 初期化
     */
    private void init() {
        try {
            Field mScroller;
            mScroller = ViewPager.class.getDeclaredField("mScroller");
            mScroller.setAccessible(true);
            Interpolator sInterpolator = new AccelerateInterpolator();
            FixedSpeedScroller scroller = new FixedSpeedScroller(this.getContext(), sInterpolator);
            mScroller.set(this, scroller);
        } catch (NoSuchFieldException e) {
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }
    }

    /**
     * Scrollの速度遅くする奴
     */
    private class FixedSpeedScroller extends Scroller {

        private static final int mDuration = 300; //ここ変えたい速度

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

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

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

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

}

なんか、うん。
パクってゴメンナサイ。

まず、このコードのすごいというか、変なところ。

Field mScroller;
mScroller = ViewPager.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);

いやー気持ち悪いですね。
本来のViewPagerクラスのprivateなmScrollerに直接アクセスして、変更をしているという。
それで、

mScroller.set(this, scroller);

setを行い新たなScrollerをセットしているんですね。

私、この書き方初めてだったので結構衝撃的だったり。
privateな所に直接アクセスするってところまではわかったんですが、

mScroller.setAccessible(true);

で、常にViewPagerのmScrollerに対してアクセスするってかなり気持ち悪いですよね。
とくにprivateな変数なので今後、変数名を変えられたら使えなくなっちゃったりするんですよね。
なんかあまり多用するものではないのかなとか思ったり。

最後に

zzz
おやすみなさい

ではではー