自定义View——循环轮播View

通过scroller实现轮播View控件:

效果:

这里写图片描述

public class BannerLoopLayout extends ViewGroup {

    private Scroller mScroller;

    public BannerLoopLayout(Context context) {
        this(context,null,0);
    }

    public BannerLoopLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public BannerLoopLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mScroller = new Scroller(context);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int w = MeasureSpec.getSize(widthMeasureSpec);
        int h = MeasureSpec.getSize(heightMeasureSpec);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            LayoutParams lp = child.getLayoutParams();
            lp.width = w;
            lp.height = h;
            child.setLayoutParams(lp);
            measureChild(child,widthMeasureSpec,heightMeasureSpec);
        }
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                if (i == childCount - 1) {
                    child.layout(-1 * getMeasuredWidth(), 0,
                            -1 * getMeasuredWidth() + child.getMeasuredWidth(),
                            child.getMeasuredHeight());
                } else {
                    child.layout(i * getMeasuredWidth(), 0,
                            i * getMeasuredWidth() + child.getMeasuredWidth(),
                            child.getMeasuredHeight());
                }
            }

    }

    private float startX;
    private float lastX;
    private int offX;
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                startX = ev.getX();
                lastX = startX;
                break;
            case MotionEvent.ACTION_MOVE:
                offX = (int) Math.abs(ev.getX() - startX);
                if (offX > 2){
                    return true;
                }
                lastX = ev.getX();
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_MOVE:
                offX = (int) (event.getX() - startX);
                scrollBy(-(int) (event.getX() - lastX), 0);
                lastX = event.getX();
                break;
            case MotionEvent.ACTION_UP:
                int scrollX;
                if (getScrollX()>0){
                    scrollX = (offX > 0)?getWidth()/4:getWidth()*3/4;
                }else {
                    scrollX = ((offX > 0)?getWidth()*3/4:getWidth()/4) * -1;
                }
                int targetIndex = (getScrollX() + scrollX) / getWidth();
                int dx = targetIndex * getWidth() - getScrollX();
                mScroller.startScroll(getScrollX(), 0, dx, 0);
                invalidate();
                checkChildLayout(targetIndex);
                break;

        }
        return super.onTouchEvent(event);
    }


    private void checkChildLayout(int targetIndex){
        int childCount = getChildCount();
        int curIndex = (targetIndex+childCount*1000)%childCount;

        View childLeft;
        if (curIndex == 0) {
            childLeft = getChildAt(childCount - 1);
        }else {
            childLeft = getChildAt(curIndex - 1);
        }
        childLeft.layout((targetIndex-1)*childLeft.getWidth()
                ,0,targetIndex*childLeft.getWidth(),childLeft.getHeight());

        View childRight;
        if (curIndex == childCount-1) {
            childRight = getChildAt(0);

        }else {
            childRight = getChildAt(curIndex + 1);
        }
        childRight.layout((targetIndex+1)*childRight.getWidth()
                ,0,(targetIndex+2)*childRight.getWidth(),childRight.getHeight());

    }
    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()){
            scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
            invalidate();
        }
    }
}

布局文件:

 <com.rong.launchmode.view.BannerLoopLayout
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="100dp">
        <Button
            android:textSize="30sp"
            android:text="btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:textSize="25sp"
            android:text="btn2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:textSize="20sp"
            android:text="btn3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:textSize="15sp"
            android:text="btn4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </com.rong.launchmode.view.BannerLoopLayout>

有点赶时间。。还没来得及注释,先发表再说。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值