自定义优惠券

来源:互联网 发布:宁波加工中心编程招聘 编辑:程序博客网 时间:2024/03/29 17:25

最近做项目的时候,加入优惠券模块,效果图如下:

最终效果图

下面简单的说下实现过程。

  • 首先是自定义了一个控件CouponView,该控件继承了LinearLayout,该控件有如下几个自定义属性:
<declare-styleable name="CouponView">        <attr name="radius" format="dimension"/>        <attr name="sawtooth_color" format="color"/>        <attr name="background_color" format="color"/>        <attr name="sawtooth_width_gap" format="dimension"/>        <attr name="sawtooth_weight" format="float"/>    </declare-styleable>

其中radius表示的是右边那列小锯齿的半径大小,sawtooth_color表示左边的锯齿部分的背景颜色,background_color表示整体的背景颜色,sawtooth_width_gap表示锯齿之间的间隙大小,sawtooth_weight表示左边含有锯齿部分的宽度占整个布局的宽度比例。

  • 接下来在CouponView中获取到这些属性:
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CouponView);        int n = a.getIndexCount();        for (int i = 0; i < n; i++) {            int attr = a.getIndex(i);            switch (attr) {                case R.styleable.CouponView_radius:                    mRRadius = a.getDimension(attr, 10);                    break;                case R.styleable.CouponView_sawtooth_color:                    mSawtoothColor = a.getColor(attr, 0);                    break;                case R.styleable.CouponView_sawtooth_width_gap:                    mRCircleGap = a.getDimension(attr, 8);                    break;                case R.styleable.CouponView_sawtooth_weight:                    mSawtoothWeight = a.getFloat(attr, 0.65f);                    break;                case R.styleable.CouponView_background_color:                    mBackgroundColor = a.getColor(attr, 0);            }        }        a.recycle();

获取参数这个没什么好说的,获取完参数之后别忘了初始化Paint,还有千万别漏了setWillNotDraw(false),如果不设置该属性为false,onDraw有可能不会被调用到:

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.FILL);        //别忘了将该属性设置为false        setWillNotDraw(false);
  • 接着根据既有数值算出锯齿的个数及剩余空间:
@Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        if(changed) {            //计算剩余空间            if (mRRemain == 0) {                mRRemain = (int) (b - t - mRCircleGap - getPaddingTop() - getPaddingBottom()) % (2 * mRRadius + mRCircleGap);            }            //计算锯齿半圆个数            mRCircleNum = (int) ((b - t - mRCircleGap - getPaddingTop() - getPaddingBottom()) / (2 * mRRadius + mRCircleGap));        }    }

这里的剩余空间是指根据指定的半径大小画了mRCircleNum个 半圆后还剩余的高度,用于指定画半圆的开始的位置。

  • 接下来就是draw的过程了:
 float width = getWidth() - getPaddingLeft() - getPaddingRight();        float height = getHeight() - getPaddingTop() - getPaddingBottom();        mPaint.setColor(mSawtoothColor);        //画锯齿背景        canvas.drawRect(getPaddingLeft(), getPaddingTop(), getPaddingLeft() + (width * mSawtoothWeight), getPaddingTop() + height, mPaint);        mPaint.setColor(mBackgroundColor);        //画锯齿部分        for (int i = 0; i < mRCircleNum; i++) {            float y = mRCircleGap + mRRadius + mRRemain / 2 + ((mRCircleGap + mRRadius * 2) * i) + getPaddingTop();            canvas.drawCircle(getPaddingLeft() + width * mSawtoothWeight, y, mRRadius, mPaint);        }        //画右边剩余部分        canvas.drawRect(getPaddingLeft() + width * mSawtoothWeight, getPaddingTop(), width + getPaddingLeft(), height + getPaddingTop(), mPaint);mPaint);        //画左边的大的半圆        mOval.set(getPaddingLeft() - mLRadius,                getPaddingTop() + (height - 2 * mLRadius) / 2,                getPaddingLeft() + mLRadius,                getPaddingTop() + (height - 2 * mLRadius) / 2 + 2 * mLRadius);        canvas.drawArc(mOval, -90, 180, true, mPaint);

这里需要说明的是画左边的半圆用的是drawArc而不是drawCircle,因为drawCircle会画出整个圆,所以这里通过计算弧度来画半圆。其余的都比较简单,不用多说。

  • 最后在布局文件中使用就行了:
<com.example.coupondemo.view.CouponView xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:coupon="http://schemas.android.com/apk/res-auto"    coupon:background_color="@android:color/white"    coupon:sawtooth_color="@color/coupon_sawtooth_bg_color"    coupon:sawtooth_weight="0.7"    android:layout_width="match_parent"    android:layout_height="120dp"    android:paddingLeft="30dp"    android:paddingRight="30dp"    android:orientation="horizontal">

代码就这么多,基本实现了该效果。

附上代码:
CouponDemo

0 0
原创粉丝点击