一个弹性的广告板

描述

直接上图。拖动绳子的时候广告板出现,再拉绳子广告板收起,主要在收和拉得时候表现一种弹性的感觉。



思路

1.通过继承viewgroup来实现,包括2个基本元素:广告板和拉绳
2.通过监听绳子的ontouch事件来获取拉伸广告板的动作
3.通过scroller类来实现view弹性滑动(当然通过延时动画也是一种思路) 

实战

1.先把包含广告板和绳子的布局加载到自定义view中

View view = LayoutInflater.from(context).inflate(R.layout.curtain, null, false);
adImg = (ImageView) view.findViewById(R.id.img_curtain_ad);
ropeImg = (ImageView) view.findViewById(R.id.img_curtain_rope);
addView(view);

2.重写绳子的ontouch()方法,监听绳子的动作

@Override
public boolean onTouch(View v, MotionEvent event) {
    if (isMove) {
        return false;
    }
    y = event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            //跟手滑动
            scrollBy(0, (int) (mLastY - y));
            break;
        case MotionEvent.ACTION_UP:
            //松手时将布局放到正确的位置,弹性的
            if (isOpen) {
                mScroller.startScroll(0, mScroller.getFinalY(), 0, adHeight - mScroller.getFinalY(), duration);
            } else {
                mScroller.startScroll(0, mScroller.getFinalY(), 0, 0 - mScroller.getFinalY(), duration);
            }
            isOpen = !isOpen;

            invalidate();
            break;
        default:
            break;
    }

    mLastY = y;

    return true;
}

3.注意上边scroller的用法,同时要重写computeScroll(),下边是computeScroll()的常用写法

@Override
public void computeScroll() {
   //先判断mScroller滚动是否完成
     if (mScroller.computeScrollOffset())
     {
               //这里调用View的scrollTo()完成实际的滚动
          scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
           //必须调用该方法,否则不一定能看到滚动效果
          postInvalidate();
       }
       super.computeScroll();
}

4.最后附上完整的代码

public class CurtainView extends RelativeLayout implements View.OnTouchListener {
    private Scroller mScroller;
    private ImageView adImg,ropeImg;
    private int adHeight;
    private float mLastY,y;
    //是否动画
    private boolean isMove = false;
    //是否打开
    private boolean isOpen = false;
    //动画时间
    private static final int duration = 1500;

    public CurtainView(Context context) {
        super(context);
        init(context);
    }

    public CurtainView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        Interpolator interpolator = new BounceInterpolator();
        mScroller = new Scroller(context, interpolator);

        //设置透明背景
        this.setBackgroundColor(Color.argb(0, 0, 0, 0));

        View view = LayoutInflater.from(context).inflate(R.layout.curtain, null, false);
        adImg = (ImageView) view.findViewById(R.id.img_curtain_ad);
        ropeImg = (ImageView) view.findViewById(R.id.img_curtain_rope);
        addView(view);

        //先把广告板一次起来
        post(new Runnable() {
            @Override
            public void run() {
                adHeight = adImg.getHeight();
                CurtainView.this.scrollTo(0, adHeight);
            }
        });

        ropeImg.setOnTouchListener(this);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (isMove) {
            return false;
        }
        y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                scrollBy(0, (int) (mLastY - y));
                break;
            case MotionEvent.ACTION_UP:
                if (isOpen) {
                    mScroller.startScroll(0, mScroller.getFinalY(), 0, adHeight - mScroller.getFinalY(), duration);
                } else {
                    mScroller.startScroll(0, mScroller.getFinalY(), 0, 0 - mScroller.getFinalY(), duration);
                }
                isOpen = !isOpen;
                //必须执行invalidate才能保证computeScroll被调用到
                invalidate();
                break;
            default:
                break;
        }

        mLastY = y;

        return true;
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            postInvalidate();
            isMove = true;
        } else {
            isMove = false;
        }

        super.computeScroll();
    }
}

结论

1.主要是scroller的使用,注意scrollBy和scrollTo的区别
2.项目中使用上边的例子请自行改造 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值