垂直滚动组件

一、效果图


垂直滚动组件_第1张图片
ezgif.com-video-to-gif.gif

二、简单分析
1、要保证view垂直滚动
2、数据集合不定
3、view的缓存/复用
三、设计
简易的效仿经典的ListView组件,适配器处理数据,view显示布局。
1、自定义YverticalView继承FrameLayout,作为滚动view的父布局,view的滚动可选择scroll和值动画,值动画使用较为简便
2、初始化
可初始化值动画,设置插值器,匀速滑动

    public void init() {
        if (mValueAnimator == null) {
            mValueAnimator = ValueAnimator.ofFloat(0, 1f);
        }
        mValueAnimator.setDuration(mDuration);
        mValueAnimator.setInterpolator(new LinearInterpolator());
    }

3、加载子view过程判断数据的个数:
=0:不加载view
=1:加载一个view
当>1:加载两个view
因为垂直滚动过程最多同时显示2条子view,即使N条数据仅加载两个子view。这点ListView和RecyclerView中使用的ViewHolder缓存item布局中的view,防止多次加载引发内存溢出。
4、本自定义YverticalView直接强制初始化两个mFirstview, mSecondView作为滚动的子view
当数据>1时,add子view的时候,保证mSecondView位于mFirstview下方为YverticalView的高度,同时开启动画

else if (mAdapter.getCount() > 1) {
            mCorrentState = STATE_VERTICAL;
            mFirstview = mAdapter.getLayout(this);
            mSecondView = mAdapter.getLayout(this);
            FrameLayout.LayoutParams layoutParams = (LayoutParams) 
            mSecondView.getLayoutParams();
            layoutParams.setMargins(0, mHeight, 0, 0);
            addView(mFirstview);
            addView(mSecondView);
            initAnim();
            postDelayed(animRunnable, mDuration);
        }

5、动画过程中通过适配器绑定view和data

 public YverticalView initAnim() {
        mAdapter.bindView(mPosition % mAdapter.getCount(), mFirstview);
        mAdapter.bindView((mPosition + 1) % mAdapter.getCount(), mSecondView);
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mAnimValue = (float) animation.getAnimatedValue();
                scrollAnim();
                invalidate();
            }
        });
        mValueAnimator.start();
        return this;
    }

6、使用post重复执行值动画

    private AnimRunnable animRunnable = new AnimRunnable();

    private class AnimRunnable implements Runnable {

        @Override
        public void run() {
            mPosition++;
            mValueAnimator.cancel();
            initAnim();
            postDelayed(animRunnable, mDuration);
        }
    }

7、关于适配器
两点作用:
加载item布局,即YverticalView中的mFirstview, mSecondView
根据子view的滚动过程,绑定数据
核心:

    public abstract View setLayout(YverticalView yverticalView);

    public abstract void bindView(int position, View view);

    public View getLayout(YverticalView yverticalView) {
        return setLayout(yverticalView);
    }

8、最后,在YverticalView回收的时候不要忘记关闭值动画:

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        stopScroll();
    }
    public void stopScroll() {
        if (mValueAnimator != null) {
            mValueAnimator.cancel();
        }
    }

四、demo
自定义垂直滚动demo

你可能感兴趣的:(垂直滚动组件)