美文网首页
垂直滚动组件

垂直滚动组件

作者: xandone | 来源:发表于2017-06-19 22:24 被阅读21次

    一、效果图


    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

    相关文章

      网友评论

          本文标题:垂直滚动组件

          本文链接:https://www.haomeiwen.com/subject/jpunqxtx.html