viewpager from getting started to proficient in 4 optimized round robin viewpagerscroller pagetransformer

Keywords: github

Last blog Viewpager from beginner to proficient in 3 infinite round robin viewpager We have made an infinite polling viewpager, but the effect of this pager is not very appropriate, and the sliding is not very beautiful. Here we need two AIDS to help our viewpager slide more smoothly.
First of all, the ViewPagerScroller code is as follows

public class ViewPagerScroller extends Scroller {
    private int mDuration;

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

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

    public void setDuration(int mDuration) {
        this.mDuration = mDuration;
    }

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

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

These are the methods of the implemented Scroller. Next, we will put the scorer into the custom viewpager.

public class MyViewPager extends ViewPager {
    private static final int START_SCROLL_ANIM = 0;//Turn on scrolling
    private static final int STOP_SCROLL_ANIM = 1;//Turn off scrolling
    private static final int LOOP_MESSAGE = 2;//Circular message
    MyHeaderPagerHandler handler;
    private int changePagerSpeed = 2000;//Switch page speed
    private int loopSpeed = 3000;//Switching interval of each item
    private boolean ifStopAnim = false;

    public MyViewPager(Context context) {
        this(context, null);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        handler = new MyHeaderPagerHandler(new WeakReference<>(this));
        setViewPagerScrollSpeed();
    }
    //pager switch control--------------------------------------------------------------------------------------------------------------------------
    private void setViewPagerScrollSpeed() {
        try {
            Field field = ViewPager.class.getDeclaredField("mScroller");
            field.setAccessible(true);
            ViewPagerScroller viewPagerScroller = new ViewPagerScroller(getContext(), new AccelerateDecelerateInterpolator());
            field.set(this, viewPagerScroller);
            viewPagerScroller.setDuration(changePagerSpeed);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    //Sliding control--------------------------------------------------------------------------------------------------------------------------
    public void startScroll() {
        ifStopAnim = false;
        Message message = new Message();
        message.what = START_SCROLL_ANIM;
        handler.sendMessage(message);
    }

    public void startScroll(long delay) {
        ifStopAnim = false;
        Message message = new Message();
        message.what = START_SCROLL_ANIM;
        handler.sendMessageDelayed(message, delay);
    }

    public void stopScroll() {
        ifStopAnim = true;
        handler.removeCallbacksAndMessages(null);
    }

    private void loopMessage() {
        Message message = new Message();
        message.what = LOOP_MESSAGE;
        handler.sendMessageDelayed(message, loopSpeed);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                stopScroll();
                break;
            case MotionEvent.ACTION_UP:
                startScroll(6000);
                break;
        }
        return super.onTouchEvent(ev);
    }

    private static class MyHeaderPagerHandler extends Handler {
        private WeakReference<MyViewPager> myPager;

        MyHeaderPagerHandler(WeakReference<MyViewPager> myPager) {
            this.myPager = myPager;
        }

        @Override
        public void handleMessage(Message msg) {
            if (myPager.get() == null) return;
            if (myPager.get().ifStopAnim) return;
            super.handleMessage(msg);
            switch (msg.what) {
                case START_SCROLL_ANIM:
                    myPager.get().loopMessage();
                    break;
                case STOP_SCROLL_ANIM:
                    break;
                case LOOP_MESSAGE:
                    myPager.get().setCurrentItem(myPager.get().getCurrentItem() + 1, true);
                    myPager.get().loopMessage();
                    break;
            }
        }
    }
}

The key point is to use setViewPagerScrollSpeed. We get the msccroller Field through reflection, and then use field.set(this, viewPagerScroller); viewPagerScroller.setDuration(changePagerSpeed); set the switching time and the switching animation. Here, I choose acceleratedelerateinterpolator, which is the animation differentiator at the beginning of slow intermediate addition Speed up and then slow down.
In fact, our viewpager has been sliding very smoothly. In order to improve the display effect, we can add a PageTransformer to the viewpager to change the effect of the sliding process.
The code is as follows

public class MyPageTransform implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.85f;
    private static final float MIN_ALPHA = 0.5f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();
        if (position < -1) { // [-Infinity,-1)
            view.setAlpha(0);
        } else if (position <= 1) { // [- 1,1] / / slide page a to page b; page a from 0.0-1; page b from 1 to 0.0
            float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
            float vertMargin = pageHeight * (1 - scaleFactor) / 2;
            float horzMargin = pageWidth * (1 - scaleFactor) / 2;
            if (position < 0) {
                view.setTranslationX(horzMargin - vertMargin / 2);
            } else {
                view.setTranslationX(-horzMargin + vertMargin / 2);
            }
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);
            view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
        } else { // (1,+Infinity]// This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}

The implementation is also very simple. The next step is to call the procedure code as follows.

public class MainActivity4 extends AppCompatActivity {
    private MyViewPager vp_mian1;
    private MyPagerAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main4);
        vp_mian1 = findViewById(R.id.vp_mian1);
        List<View> itemViews = installItems();
        adapter = new MyPagerAdapter(itemViews);
        vp_mian1.setAdapter(adapter);
        vp_mian1.setCurrentItem(itemViews.size() * 500);
        vp_mian1.setPageTransformer(true, new MyPageTransform());
        vp_mian1.startScroll();
    }

    public List<View> installItems() {
        List<View> views = new ArrayList<>();
        int drawables[] = {R.drawable.d_01, R.drawable.d_02, R.drawable.d_03, R.drawable.d_04, R.drawable.d_05};
        for (int i = 0; i < 5; i++) {
            RelativeLayout rlHeaderItem = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.header_pager_view, null);
            ImageView ivItem = rlHeaderItem.findViewById(R.id.iv_header_item);
            ivItem.setBackgroundDrawable(getResources().getDrawable(drawables[i]));
            views.add(rlHeaderItem);
        }
        return views;
    }

    @Override
    protected void onDestroy() {
        vp_mian1.stopScroll();
        super.onDestroy();
    }
}

Set the pagetransform of the viewpager through VP [mian1. Setpagetransformer (true, new mypagetransform()); so that the effect of the viewpager is more beautiful.
Next, we introduce adding viewpager to listview's header view.
GitHub portal click here

Posted by frans-jan on Thu, 02 Jan 2020 21:57:03 -0800