自定义邮票锯齿背景效果
来源:互联网 发布:全国计算机考试软件 编辑:程序博客网 时间:2024/05/20 14:44
简介
最近项目中有一个需求,需要做一个类似于邮票那样的背景效果,它主要是由半圆锯齿和虚线边框结合而成。
效果图:
我用到的效果是上面图中的第一种,四周边缘是半圆锯齿,内部是虚线边框。当然,具体效果可以根据自定义属性自己定制。
使用
1、在attr.xml
中定义属性
<declare-styleable name="StampView"> <!-- 半圆之间间距 --> <attr name="sv_semicircle_gap" format="dimension|reference" /> <!-- 半圆半径 --> <attr name="sv_semicircle_radius" format="dimension|reference" /> <!-- 半圆颜色 --> <attr name="sv_semicircle_color" format="color|reference" /> <!-- 半圆覆盖线宽 --> <attr name="sv_semicircle_cover_stroke_width" format="dimension|reference" /> <!-- 半圆覆盖颜色 --> <attr name="sv_semicircle_cover_color" format="color|reference" /> <!-- 开启顶部半圆曲线 --> <attr name="sv_semicircle_top" format="boolean|reference" /> <!-- 开启底部半圆曲线 --> <attr name="sv_semicircle_bottom" format="boolean|reference" /> <!-- 开启左边半圆曲线 --> <attr name="sv_semicircle_left" format="boolean|reference" /> <!-- 开启右边半圆曲线 --> <attr name="sv_semicircle_right" format="boolean|reference" /> <!-- 虚线的长度 --> <attr name="sv_dash_line_length" format="dimension|reference" /> <!-- 虚线的间距 --> <attr name="sv_dash_line_gap" format="dimension|reference" /> <!-- 虚线的高度 --> <attr name="sv_dash_line_height" format="dimension|reference" /> <!-- 虚线的颜色 --> <attr name="sv_dash_line_color" format="color|reference" /> <!-- 顶部虚线距离View顶部的距离 --> <attr name="sv_dash_line_top" format="boolean|reference" /> <!-- 底部虚线距离View底部的距离 --> <attr name="sv_dash_line_bottom" format="boolean|reference" /> <!-- 左侧虚线距离View左侧的距离 --> <attr name="sv_dash_line_left" format="boolean|reference" /> <!-- 右侧虚线距离View右侧的距离 --> <attr name="sv_dash_line_right" format="boolean|reference" /> <!-- 开启顶部虚线 --> <attr name="sv_dash_line_margin_top" format="dimension|reference" /> <!-- 开启底部虚线 --> <attr name="sv_dash_line_margin_bottom" format="dimension|reference" /> <!-- 开启左边虚线 --> <attr name="sv_dash_line_margin_left" format="dimension|reference" /> <!-- 开启左边虚线 --> <attr name="sv_dash_line_margin_right" format="dimension|reference" /></declare-styleable>
2、布局文件
<com.wiggins.stampview.widget.StampViewLinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/margin_normal" android:background="@drawable/stamp_view_bg" android:orientation="vertical" app:sv_semicircle_bottom="true" app:sv_semicircle_color="@color/theme_bg" app:sv_semicircle_cover_color="@color/red" app:sv_semicircle_cover_stroke_width="1dp" app:sv_semicircle_gap="5dp" app:sv_semicircle_left="true" app:sv_semicircle_radius="2.5dp" app:sv_semicircle_right="true" app:sv_semicircle_top="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="80dp" android:orientation="vertical"> </LinearLayout></com.wiggins.stampview.widget.StampViewLinearLayout>
3、自定义StampView
获取自定义属性值
public StampView(View view, Context context, AttributeSet attrs, int defStyle) { this.context = context; this.view = view; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StampView, defStyle, 0); semicircleRadius = a.getDimensionPixelSize(R.styleable.StampView_sv_semicircle_radius, dp2Px(DEFAULT_SEMICIRCLE_RADIUS)); semicircleGap = a.getDimensionPixelSize(R.styleable.StampView_sv_semicircle_gap, dp2Px(DEFAULT_SEMICIRCLE_GAP)); semicircleCoverStrokeWidth = a.getDimensionPixelSize(R.styleable.StampView_sv_semicircle_cover_stroke_width, dp2Px(DEFAULT_SEMICIRCLE_COVER_STROKE_WIDTH)); semicircleColor = a.getColor(R.styleable.StampView_sv_semicircle_color, DEFAULT_SEMICIRCLE_COLOR); semicircleCoverColor = a.getColor(R.styleable.StampView_sv_semicircle_cover_color, DEFAULT_SEMICIRCLE_COLOR); isSemicircleTop = a.getBoolean(R.styleable.StampView_sv_semicircle_top, isSemicircleTop); isSemicircleBottom = a.getBoolean(R.styleable.StampView_sv_semicircle_bottom, isSemicircleBottom); isSemicircleLeft = a.getBoolean(R.styleable.StampView_sv_semicircle_left, isSemicircleLeft); isSemicircleRight = a.getBoolean(R.styleable.StampView_sv_semicircle_right, isSemicircleRight); dashLineLength = a.getDimensionPixelSize(R.styleable.StampView_sv_dash_line_length, dp2Px(DEFAULT_DASH_LINE_LENGTH)); dashLineHeight = a.getDimensionPixelSize(R.styleable.StampView_sv_dash_line_height, dp2Px(DEFAULT_DASH_LINE_HEIGHT)); dashLineGap = a.getDimensionPixelSize(R.styleable.StampView_sv_dash_line_gap, dp2Px(DEFAULT_DASH_LINE_GAP)); dashLineColor = a.getColor(R.styleable.StampView_sv_dash_line_color, DEFAULT_DASH_LINE_COLOR); isDashLineTop = a.getBoolean(R.styleable.StampView_sv_dash_line_top, isDashLineTop); isDashLineBottom = a.getBoolean(R.styleable.StampView_sv_dash_line_bottom, isDashLineBottom); isDashLineLeft = a.getBoolean(R.styleable.StampView_sv_dash_line_left, isDashLineLeft); isDashLineRight = a.getBoolean(R.styleable.StampView_sv_dash_line_right, isDashLineRight); dashLineMarginTop = a.getDimensionPixelSize(R.styleable.StampView_sv_dash_line_margin_top, dp2Px(DEFAULT_DASH_LINE_MARGIN)); dashLineMarginBottom = a.getDimensionPixelSize(R.styleable.StampView_sv_dash_line_margin_bottom, dp2Px(DEFAULT_DASH_LINE_MARGIN)); dashLineMarginLeft = a.getDimensionPixelSize(R.styleable.StampView_sv_dash_line_margin_left, dp2Px(DEFAULT_DASH_LINE_MARGIN)); dashLineMarginRight = a.getDimensionPixelSize(R.styleable.StampView_sv_dash_line_margin_right, dp2Px(DEFAULT_DASH_LINE_MARGIN)); a.recycle(); init();}
初始化画笔
private void init() { semicirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); semicirclePaint.setDither(true); semicirclePaint.setColor(semicircleColor); semicirclePaint.setStyle(Paint.Style.FILL); semicirclePaintCover = new Paint(Paint.ANTI_ALIAS_FLAG); semicirclePaintCover.setDither(true); semicirclePaintCover.setColor(semicircleCoverColor); semicirclePaintCover.setStyle(Paint.Style.STROKE); semicirclePaintCover.setStrokeWidth(semicircleCoverStrokeWidth); dashLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); dashLinePaint.setDither(true); dashLinePaint.setColor(dashLineColor); dashLinePaint.setStyle(Paint.Style.FILL);}
获取View
宽高
public void onSizeChanged(int w, int h) { viewWidth = w; viewHeight = h; calculate();}
计算半圆锯齿和虚线边框数量和剩余距离
private void calculate() { if (isSemicircleTop || isSemicircleBottom) { remindSemicircleX = (int) ((viewWidth - semicircleGap) % (2 * semicircleRadius + semicircleGap)); semicircleNumX = (int) ((viewWidth - semicircleGap) / (2 * semicircleRadius + semicircleGap)); } if (isSemicircleLeft || isSemicircleRight) { remindSemicircleY = (int) ((viewHeight - semicircleGap) % (2 * semicircleRadius + semicircleGap)); semicircleNumY = (int) ((viewHeight - semicircleGap) / (2 * semicircleRadius + semicircleGap)); } if (isDashLineTop || isDashLineBottom) { remindDashLineX = (int) ((viewWidth + dashLineGap - dashLineMarginLeft - dashLineMarginRight) % (dashLineLength + dashLineGap)); dashLineNumX = (int) ((viewWidth + dashLineGap - dashLineMarginLeft - dashLineMarginRight) / (dashLineLength + dashLineGap)); } if (isDashLineLeft || isDashLineRight) { remindDashLineY = (int) ((viewHeight + dashLineGap - dashLineMarginTop - dashLineMarginBottom) % (dashLineLength + dashLineGap)); dashLineNumY = (int) ((viewHeight + dashLineGap - dashLineMarginTop - dashLineMarginBottom) / (dashLineLength + dashLineGap)); }}
View
绘制
public void onDraw(Canvas canvas) { if (isSemicircleTop) { for (int i = 0; i < semicircleNumX; i++) { float x = semicircleGap + semicircleRadius + remindSemicircleX / 2 + (semicircleGap + semicircleRadius * 2) * i; canvas.drawCircle(x, 0, semicircleRadius, semicirclePaint); canvas.drawCircle(x, 0, semicircleRadius, semicirclePaintCover); } } if (isSemicircleBottom) { for (int i = 0; i < semicircleNumX; i++) { float x = semicircleGap + semicircleRadius + remindSemicircleX / 2 + (semicircleGap + semicircleRadius * 2) * i; canvas.drawCircle(x, viewHeight, semicircleRadius, semicirclePaint); canvas.drawCircle(x, viewHeight, semicircleRadius, semicirclePaintCover); } } if (isSemicircleLeft) { for (int i = 0; i < semicircleNumY; i++) { float y = semicircleGap + semicircleRadius + remindSemicircleY / 2 + (semicircleGap + semicircleRadius * 2) * i; canvas.drawCircle(0, y, semicircleRadius, semicirclePaint); canvas.drawCircle(0, y, semicircleRadius, semicirclePaintCover); } } if (isSemicircleRight) { for (int i = 0; i < semicircleNumY; i++) { float y = semicircleGap + semicircleRadius + remindSemicircleY / 2 + (semicircleGap + semicircleRadius * 2) * i; canvas.drawCircle(viewWidth, y, semicircleRadius, semicirclePaint); canvas.drawCircle(viewWidth, y, semicircleRadius, semicirclePaintCover); } } if (isDashLineTop) { for (int i = 0; i < dashLineNumX; i++) { float x = dashLineMarginLeft + remindDashLineX / 2 + (dashLineGap + dashLineLength) * i; canvas.drawRect(x, dashLineMarginTop, x + dashLineLength, dashLineMarginTop + dashLineHeight, dashLinePaint); } } if (isDashLineBottom) { for (int i = 0; i < dashLineNumX; i++) { float x = dashLineMarginLeft + remindDashLineX / 2 + (dashLineGap + dashLineLength) * i; canvas.drawRect(x, viewHeight - dashLineHeight - dashLineMarginBottom, x + dashLineLength, viewHeight - dashLineMarginBottom, dashLinePaint); } } if (isDashLineLeft) { for (int i = 0; i < dashLineNumY; i++) { float y = dashLineMarginTop + remindDashLineY / 2 + (dashLineGap + dashLineLength) * i; canvas.drawRect(dashLineMarginLeft, y, dashLineMarginLeft + dashLineHeight, y + dashLineLength, dashLinePaint); } } if (isDashLineRight) { for (int i = 0; i < dashLineNumY; i++) { float y = dashLineMarginTop + remindDashLineY / 2 + (dashLineGap + dashLineLength) * i; canvas.drawRect(viewWidth - dashLineMarginRight - dashLineHeight, y, viewWidth - dashLineMarginRight, y + dashLineLength, dashLinePaint); } }}
4、定制自己的StampViewLinearLayout
StampViewLinearLayout
继承于LinearLayout
,除了边缘半圆锯齿和虚线边框之外,它和普通的LinearLayout
没有任何区别。可以通过StampView
这个代理类来给其他View
(比如LinearLayout
、FrameLayout
、ImageView
、TextView
等常用View
)添加锯齿边框背景。
public class StampViewLinearLayout extends LinearLayout { private StampView helper; public StampViewLinearLayout(Context context) { this(context, null); } public StampViewLinearLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public StampViewLinearLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); helper = new StampView(this, context, attrs, defStyle); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); helper.onSizeChanged(w, h); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); helper.onDraw(canvas); } public float getSemicircleGap() { return helper.getSemicircleGap(); } public void setSemicircleGap(float semicircleGap) { helper.setSemicircleGap(semicircleGap); } public float getSemicircleRadius() { return helper.getSemicircleRadius(); } public void setSemicircleRadius(float semicircleRadius) { helper.setSemicircleRadius(semicircleRadius); } public float getSemicircleCoverStrokeWidth() { return helper.getSemicircleCoverStrokeWidth(); } public void setSemicircleCoverStrokeWidth(float semicircleCoverStrokeWidth) { helper.setSemicircleCoverStrokeWidth(semicircleCoverStrokeWidth); } public int getSemicircleColor() { return helper.getSemicircleColor(); } public void setSemicircleColor(int semicircleColor) { helper.setSemicircleColor(semicircleColor); } public int getSemicircleCoverColor() { return helper.getSemicircleCoverColor(); } public void setSemicircleCoverColor(int semicircleCoverColor) { helper.setSemicircleCoverColor(semicircleCoverColor); } public boolean isSemicircleTop() { return helper.isSemicircleTop(); } public void setSemicircleTop(boolean semicircleTop) { helper.setSemicircleTop(semicircleTop); } public boolean isSemicircleBottom() { return helper.isSemicircleBottom(); } public void setSemicircleBottom(boolean semicircleBottom) { helper.setSemicircleBottom(semicircleBottom); } public boolean isSemicircleLeft() { return helper.isSemicircleLeft(); } public void setSemicircleLeft(boolean semicircleLeft) { helper.setSemicircleLeft(semicircleLeft); } public boolean isSemicircleRight() { return helper.isSemicircleRight(); } public void setSemicircleRight(boolean semicircleRight) { helper.setSemicircleRight(semicircleRight); } public float getDashLineLength() { return helper.getDashLineLength(); } public void setDashLineLength(float dashLineLength) { helper.setDashLineLength(dashLineLength); } public float getDashLineHeight() { return helper.getDashLineHeight(); } public void setDashLineHeight(float dashLineHeight) { helper.setDashLineHeight(dashLineHeight); } public float getDashLineGap() { return helper.getDashLineGap(); } public void setDashLineGap(float dashLineGap) { helper.setDashLineGap(dashLineGap); } public int getDashLineColor() { return helper.getDashLineColor(); } public void setDashLineColor(int dashLineColor) { helper.setDashLineColor(dashLineColor); } public float getDashLineMarginTop() { return helper.getDashLineMarginTop(); } public void setDashLineMarginTop(float dashLineMarginTop) { helper.setDashLineMarginTop(dashLineMarginTop); } public float getDashLineMarginBottom() { return helper.getDashLineMarginBottom(); } public void setDashLineMarginBottom(float dashLineMarginBottom) { helper.setDashLineMarginBottom(dashLineMarginBottom); } public float getDashLineMarginLeft() { return helper.getDashLineMarginLeft(); } public void setDashLineMarginLeft(float dashLineMarginLeft) { helper.setDashLineMarginLeft(dashLineMarginLeft); } public float getDashLineMarginRight() { return helper.getDashLineMarginRight(); } public void setDashLineMarginRight(float dashLineMarginRight) { helper.setDashLineMarginRight(dashLineMarginRight); } public boolean isDashLineTop() { return helper.isDashLineTop(); } public void setDashLineTop(boolean dashLineTop) { helper.setDashLineTop(dashLineTop); } public boolean isDashLineBottom() { return helper.isDashLineBottom(); } public void setDashLineBottom(boolean dashLineBottom) { helper.setDashLineBottom(dashLineBottom); } public boolean isDashLineLeft() { return helper.isDashLineLeft(); } public void setDashLineLeft(boolean dashLineLeft) { helper.setDashLineLeft(dashLineLeft); } public boolean isDashLineRight() { return helper.isDashLineRight(); } public void setDashLineRight(boolean dashLineRight) { helper.setDashLineRight(dashLineRight); }}
项目地址 ☞ 传送门
阅读全文
0 0
- 自定义邮票锯齿背景效果
- 自定义View学习之锯齿波纹效果
- CSS实现邮票效果
- CSS实现邮票效果
- android 抗锯齿效果
- iOS Tableable cell 自定义点击背景效果
- CSS实现的邮票效果
- CSS实现的邮票效果
- android 抗锯齿效果【转】
- OpenGL实现抗锯齿效果
- css-3实现锯齿效果
- CouponView 半圆锯齿背景虚线边框
- TextView + 背景设置, 产生自定义Tab选中效果
- android Ripple effect 点击 水波效果 自定义背景颜色
- AutoCompleteTextView控件自定义下拉框背景,点击效果,字体显示效果,匹配条件等效果
- 邮票
- 邮票
- 邮票
- redis微博——拉模型
- File 创建 读取 文件夹
- gdb调试基本命令列表
- 关于上拉加载的一些内容
- Socket编程(网络协议一)
- 自定义邮票锯齿背景效果
- UVa 11292 贪心
- 编写获取命令行参数Getopt函数(C++)
- 利用windowManager实现App上的logcat
- Java之——类热加载
- 微信永久二维码
- 用hexo搭建个人博客上传到github上遇到的问题,
- OpenGL ES3.0 《学习笔记 六》 Vertex Attributes, Vertex Arrays, and Buffer Objects
- 解释下关于数状数组区间更新、单点查询和区间更新、区间查询