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", 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的取值。
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Android自定義短信驗證碼組件
- 淺談Android開發Webview的Loading使用效果
- Android自定義view貝塞爾曲線
- Android實現漸變色水波紋效果
- Android自定義View用切圖顯示字符串