1. 程式人生 > 程式設計 >Android實現無限迴圈滾動

Android實現無限迴圈滾動

傳統的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",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的取值。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。