안 드 로 이 드 무한 순환 스크롤 실현

전통 적 인 ViewPager 가 순환 스크롤 을 하 는 데 는 두 가지 사고방식 이 있다.
하 나 는 count 를 Integer.MAX 로 설정 한 다음 index 에 따라 실제 수량 을 추출 하 는 것 입 니 다.
하 나 는 시작 부분 에 end 를 추가 하고 끝 에 start 를 추가 하 는 것 이다.쉽게 말 하면 두 개가 더 있 고 이 두 개 로 미 끄 러 질 때 바로 setCurrent Item 을 실제 위치 로 옮 기 는 것 이다.
pd 의 콜라 보 레이 션 순환 스크롤 을 관찰 할 때 몇 가지 실현 방식 을 생각 합 니 다.
1.Recyclerview 를 통 해 ViewPager 가 순환 스크롤 을 하 는 사고 와 비슷 하고 모든 터치 사건 을 차단 해 야 합 니 다.그러나 이런 방식 으로 는 pd 효과 처럼 들 어가 거나 나 가 는 애니메이션 을 설정 할 수 없습니다.
2.Vertical Viewpager 의 형식 을 개조 하 는 것 도 가능 할 것 같 지만 귀 찮 습 니 다.
3.사용자 정의 방식 으로 이 루어 집 니 다.(간단 하 다 고 생각 했 는데 실현 되 었 습 니 다.코드 가 많 지 않 지만 작은 디 테 일 은 주의해 야 합 니 다.)
저 는 사용자 정의 여 기 는 데모 일 뿐 아 이 디 어 를 제공 합 니 다.
가장 핵심 적 인 것 은 위 에 있 는 아 이 템 이 화면 에서 미 끄 러 질 때 제거 한 다음 사용자 정의 View Group 의 끝 에 추가 하 는 것 입 니 다.

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 에 대한 값 입 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기