Android自定义优惠券解析
2016-09-23 13:10
197 查看
自定义优惠券View在github上已经很多了,自己做也没什么特色,参考了网上的实现方式,对实现原理有了一些自己的理解,看代码总是很容易的,敲的过程去揣摩别人的思路,真正去理解才是我们要做的。
首先来看效果一:
这是网上流行的效果
看效果,主要是上下画圆,思路就是draw圆来覆盖掉布局背景,从而实现波浪效果,下面来看看怎么计算。
第一步:思考我们需要设置哪些参数
这里讲一下不能整除时的间隔,如果能整除的情况下View的width=(2*半径+间隔)*圆的个数+间隔,这样计算没有问题,但是当view的宽度比这个距离要大一点的时候,就是不满足整除的时候,最两侧的间距要稍微大一点,这就需要计算不能整除时的间隔。
效果:
这是对前人代码的理解,当然我们还需要在考虑如何在此基础添加什么的样式!
效果1:
在两侧加虚线:
距离可以根据需求来调整,这个没啥可说的额。
效果二:
加虚线边框
考虑:这样做或许只能适应自己的需求,而并不具有通用性。
要具有通用性,必须要用到自定义的属性,将种种变量封装起来,这样就可随意控制圆的大小,背景颜色,间隔大小,虚线等。
具体就不细说了,恩就先到这吧。
全部代码:
参考:
http://blog.csdn.net/u012162503/article/details/51433490
更好的:
https://github.com/dongjunkun/CouponView
首先来看效果一:
这是网上流行的效果
看效果,主要是上下画圆,思路就是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
相关文章推荐
- 解析在Android中为TextView增加自定义HTML标签的实现方法
- Android解析自定义xml文件--Sax解析xml文件,测试demo(方案二)
- 深入解析Android的自定义布局
- Android ViewDragHelper完全解析 自定义ViewGroup神器
- Android ViewDragHelper完全解析 自定义ViewGroup神器
- Android错误引用自定义资源数据类型,造成安装解析产生未知错误
- Android--ViewDragHelper完全解析 自定义ViewGroup神器
- android Volley解析之自定义CookieObjectRequest
- 【转】android 自定义View过程解析
- Android ViewDragHelper完全解析 自定义ViewGroup神器
- Android解析自定义xml文件--Pull解析xml文件,测试demo(方案三)
- 深入解析Android的自定义布局
- 深入解析Android的自定义布局
- Android自定义属性 format的深入解析
- 深入解析Android的自定义布局
- Android解析自定义xml文件(方案一)
- android 解析自定义layout
- 深入解析Android的自定义布局
- Android 对Layout_weight属性完全解析以及使用ListView来实现表格(自定义适配器)
- Android 带清除 和 晃动效果的 自定义 EditText 解析