关注

Android无限循环滚动

传统的ViewPager做循环滚动有两种思路。

  1. 一种是设置count为Integer.MAX,然后根据index对实际数量取模
  2. 一种是在开头在开头添加end,在末尾添加start。简单的说就是多两个,滑动到这两个的时候直接setCurrentItem到真正的位置。

在观察pdd的拼单的循环滚动的时候,想到几种实现方式。

  1. 通过Recyclerview,同样跟ViewPager做循环滚动的思路类似,多一点要拦截掉所有的触摸事件。但是这种方式的话无法像pdd的效果那样设置进入和出去的动画。
  2. 通过改造VerticalViewpager的形式,应该也是可以的,但是感觉比较麻烦。
  3. 通过自定义的方式实现。(原本以为挺简单的,实现了下,代码不多但是有些小细节需要注意下。)

我选择了自定义的这里只是一个demo,提供一种思路。

最核心的就是上面的item滑出屏幕的时候将它remove掉然后再加到自定义的ViewGroup的末尾。

public class LoopView extends ViewGroup {
    private static final String TAG = "LoopView";
    private float dis;
    private ObjectAnimator animator;
    private int currentIndex = 0;
    private Handler handler = new Handler(Looper.getMainLooper());

    public LoopView(Context context) {
        super(context);
        init();
    }

    public LoopView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public LoopView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    void init() {
        View view1 = new View(getContext());
        view1.setTag("gray");
        view1.setBackgroundColor(Color.GRAY);
        LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, 200);
        addView(view1, layoutParams);

        View view2 = new View(getContext());
        view2.setTag("red");
        view2.setBackgroundColor(Color.RED);
        LayoutParams layoutParams1 = new LayoutParams(LayoutParams.MATCH_PARENT, 200);
        addView(view2, layoutParams1);

        View view3 = new View(getContext());
        view3.setTag("green");
        view3.setBackgroundColor(Color.GREEN);
        LayoutParams layoutParams2 = new LayoutParams(LayoutParams.MATCH_PARENT, 200);
        addView(view3, layoutParams2);

        animator = ObjectAnimator.ofFloat(this, "dis", 0, 1);
        animator.setDuration(2000);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                currentIndex++;
                View first = getChildAt(0);
                removeView(first);
                addView(first);
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        animator.clone().start();
                    }
                }, 3000);
            }
        });

    }

    public void start() {
        animator.start();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(200, MeasureSpec.EXACTLY));
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
        int top = currentIndex * getMeasuredHeight();
        for (int i = 0; i < childCount; i++) {
            View childAt = getChildAt(i);
            childAt.layout(l, top, r, top + childAt.getMeasuredHeight());
            top += childAt.getMeasuredHeight();
        }
    }

    public float getDis() {
        return dis;
    }

    public void setDis(float dis) {
        this.dis = dis;
        float disY = dis * getHeight();
        scrollTo(0, (int) (currentIndex * getHeight() + disY));
    }
}

需要注意的就是onLayout的时候对于top的取值。

转载自CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/qq_28302795/article/details/112017591

文章分类Android

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--