Android自定义优惠券解析

自定义优惠券View在github上已经很多了,自己做也没什么特色,参考了网上的实现方式,对实现原理有了一些自己的理解,看代码总是很容易的,敲的过程去揣摩别人的思路,真正去理解才是我们要做的。

首先来看效果一:

这是网上流行的效果

这里写图片描述

看效果,主要是上下画圆,思路就是draw圆来覆盖掉布局背景,从而实现波浪效果,下面来看看怎么计算。

第一步:思考我们需要设置哪些参数

   //圆的半径
    private int radius=10;
    //间隔长度
    private int mLength=8;
    //画笔
    private Paint mPaint;
    //圆的个数
    private int mCircleNum;
    //不能整除时的间隔
    private int remain;

这里讲一下不能整除时的间隔,如果能整除的情况下View的width=(2*半径+间隔)*圆的个数+间隔,这样计算没有问题,但是当view的宽度比这个距离要大一点的时候,就是不满足整除的时候,最两侧的间距要稍微大一点,这就需要计算不能整除时的间隔。

 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //获取不能整除时的间隔
        remain = (w - mLength) % (2 * radius + mLength);
        //获取圆的个数
        mCircleNum = (w - mLength) / (2 * radius + mLength);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < mCircleNum; i++) {
            //计算圆x轴的坐标
            float x = mLength + radius + remain / 2 + ((mLength + radius * 2) * i);
            //上边花园
            canvas.drawCircle(x, 0, radius, mPaint);
            //下边画圆
            canvas.drawCircle(x, getHeight(), radius, mPaint);
        }
        }

效果:

这里写图片描述

这是对前人代码的理解,当然我们还需要在考虑如何在此基础添加什么的样式!

效果1:

这里写图片描述

在两侧加虚线:

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        //加虚线
        paint.setPathEffect(new DashPathEffect(new float[]{24, 12}, 0));
        paint.setStrokeWidth(6);
        //只能路径加虚线,drawLine不行
        Path path=new Path();
        path.moveTo(remain/2+mLength+2*radius, 2*radius);
        path.lineTo(remain/2+mLength+2*radius, getHeight()-2*radius);
        canvas.drawPath(path, paint);
        //右侧虚线
        Path path2=new Path();
        path2.moveTo(getWidth()-remain/2-mLength-2*radius,2*radius);
        path2.lineTo(getWidth()-remain/2-mLength-2*radius,getHeight()-2*radius);
        canvas.drawPath(path2, paint);

距离可以根据需求来调整,这个没啥可说的额。

效果二:

这里写图片描述

加虚线边框

        Path path3=new Path();
        //左上坐标起点
        path3.moveTo(remain/2+mLength, 2*radius);
        //左下坐标
        path3.lineTo(remain/2+mLength, getHeight()-2*radius);
        //右下坐标
        path3.lineTo(getWidth()-remain/2-mLength,getHeight()-2*radius);
        //右上坐标
        path3.lineTo(getWidth()-remain/2-mLength,2*radius);
        //关闭边框
        path3.close();
        canvas.drawPath(path3, paint);

考虑:这样做或许只能适应自己的需求,而并不具有通用性。

要具有通用性,必须要用到自定义的属性,将种种变量封装起来,这样就可随意控制圆的大小,背景颜色,间隔大小,虚线等。

具体就不细说了,恩就先到这吧。

全部代码:

package com.example.com.testview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.widget.LinearLayout;

/**
 * Created by Administrator on 2016/9/23.
 */

public class CardViews extends LinearLayout {
    //圆的半径
    private int radius = 10;
    //间隔长度
    private int mLength = 8;
    //画笔
    private Paint mPaint;
    //圆的个数
    private int mCircleNum;
    //不能整除时的间隔
    private int remain;

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

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

    public CardViews(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        remain = (w - mLength) % (2 * radius + mLength);
        mCircleNum = (w - mLength) / (2 * radius + mLength);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < mCircleNum; i++) {
            float x = mLength + radius + remain / 2 + ((mLength + radius * 2) * i);
            canvas.drawCircle(x, 0, radius, mPaint);
            canvas.drawCircle(x, getHeight(), radius, mPaint);
        }
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        paint.setPathEffect(new DashPathEffect(new float[]{24, 12}, 0));
        paint.setStrokeWidth(6);
//        Path path=new Path();
//        path.moveTo(remain/2+mLength+2*radius, 2*radius);
//        path.lineTo(remain/2+mLength+2*radius, getHeight()-2*radius);
//        canvas.drawPath(path, paint);
//
//        Path path2=new Path();
//        path2.moveTo(getWidth()-remain/2-mLength-2*radius,2*radius);
//        path2.lineTo(getWidth()-remain/2-mLength-2*radius,getHeight()-2*radius);
//        canvas.drawPath(path2, paint);

        Path path3=new Path();
        path3.moveTo(remain/2+mLength, 2*radius);
        path3.lineTo(remain/2+mLength, getHeight()-2*radius);
        path3.lineTo(getWidth()-remain/2-mLength,getHeight()-2*radius);
        path3.lineTo(getWidth()-remain/2-mLength,2*radius);
        path3.close();
        canvas.drawPath(path3, paint);

    }
}

参考:
http://blog.csdn.net/u012162503/article/details/51433490

更好的:
https://github.com/dongjunkun/CouponView

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值