垂直滚动组件

一、效果图


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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,371评论 25 709
  • 内容抽屉菜单ListViewWebViewSwitchButton按钮点赞按钮进度条TabLayout图标下拉刷新...
    皇小弟阅读 46,946评论 22 665
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,283评论 4 61
  • 林心如的妈妈在离婚的时候对她说了一句:“一辈子太长了” 这几天林心如这段话被转疯了:她说:爸妈离婚,就因为...
    是温暖呀阅读 606评论 0 0
  • 无欲无求 甚至连个想念的人都没有 就像这颗心一样 是个空白 总感觉少了点什么东西 却又无以言状 丶 我也不知道自己...
    灵夕丶阅读 250评论 0 2