ViewPager2解析

167 阅读1分钟

ViewPager2主要是为了解决ViewPager的痛点,ViewPager2支持 right-to-left布局,垂直方向的滚动,可修改Fragment list,当fragment list改变时,可以通过adpter.notifydatachanged()更新界面.

Viewpager2

ViewPager2通过setAdpter(),设置数据,在ViewPager2中维护了一个RecyclerView,因此ViewPager2的使用与RecyclerView的使用方法一致.前面是一些layoutmanager等常规用法,setOrientation()设置滑动方向,

#ViewPager2构造方法
private void initialize(Context context, AttributeSet attrs) {
    ......
    //在ViewPager2中new一个RecyclerView 
    //设置了RecyclerView子布局的focusabl以及设置了最小滑动限制
    //添加了子View Attach的监听
    mRecyclerView = new RecyclerViewImpl(context);
    mRecyclerView.setId(ViewCompat.generateViewId());
    mRecyclerView.setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS);
    mLayoutManager = new LinearLayoutManagerImpl(context);
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setScrollingTouchSlop(RecyclerView.TOUCH_SLOP_PAGING);
    setOrientation(context, attrs);
    mRecyclerView.setLayoutParams(
                new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));
    //监听子View必须为match_parent,不然抛出异常
    mRecyclerView.addOnChildAttachStateChangeListener(enforceChildFillListener());
    }

Viewpager2实现整页滑动的代码

在RecycleView的`onTouchEvent()中

@Override
public boolean onTouchEvent(MotionEvent e) {
    ......
    ```
if (!((xvel != 0 || yvel != 0) && fling((int) xvel, (int) yvel))) {
    setScrollState(SCROLL_STATE_IDLE);
}

image.png

调用fling(),如果X轴的和Y轴的速度为0,则返回false,就会走setScrollState()最终会调用dispatchOnScrollStateChanged() 然后调用滑动监听,走到SnapHelper#snapToTargetExistingView() image.png 从方法名可以看出,主要是要滑动到的View距离,然后通过调用RecyclerView的滑动方法移动到指定位置 image.png