欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android实现无限循环滚动

程序员文章站 2022-06-16 09:42:06
传统的viewpager做循环滚动有两种思路。一种是设置count为integer.max,然后根据index对实际数量取模一种是在开头在开头添加end,在末尾添加start。简单的说就是多两个,滑动...

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

一种是设置count为integer.max,然后根据index对实际数量取模
一种是在开头在开头添加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的取值。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。