经常用QQ的朋友应该知道,QQ头像是圆的。那么正方形,六边形,或者其它异形怎么实现的,其实原理都是一样的。把图片进行渲染,然后利用path指定显示区域即可。今天分享的就是六边形。
正六边形画法
正六边形的边长l就是宽的一半,正六边形的高是 Math.sqrt(3)*l ,然后可以算出正六边形顶部的top值,之后只要依次遍历连接每个点,即可画出正六边形。
float l = (float) (getWidth() / 2); float h = (float) (Math.sqrt(3)*l); float top = (getHeight() - h) / 2 ; mPath.reset(); mPath.moveTo(l/2,top); mPath.lineTo(0,h/2+top); mPath.lineTo(l/2,h+top); mPath.lineTo((float) (l*1.5),h+top); mPath.lineTo(2*l,h/2+top); mPath.lineTo((float) (l*1.5),top); mPath.lineTo(l/2,top); mPath.close();
设置Shader
对于Shader还不了解的人,可以去搜一搜其他博客,讲这个的已经很多了,我就不再讲一遍了。这里我们使用的是BitmapShader,这个类名副其实,它可以把一个Bitmap做为我们的渲染对象,在设置Bitmap的时候把Bitmap初始化BitmapShader,然后设置给Paint。直接上代码了。
// 先把要设置的bitmap设置给一个BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) ; // 然后给Paint设置shader mPaint.setShader(shader);
使用Shader绘制正六边形
我们重写onDraw方法:
@Override public void onDraw(Canvas canvas) { canvas.drawPath(mPath,mPaint); }
封装到Drawable中
public class HiveDrawable extends Drawable { // 用于记录边界信息的Rect Rect mRect = new Rect(); Paint mPaint; Path mPath ; BitmapShader mShader; Bitmap mBitmap ; public HiveDrawable() { this(null) ; } public HiveDrawable(Bitmap bitmap) { init(); setBitmap(bitmap); } private void init() { initPaint() ; initPath() ; } private void ensurePaint(){ if (mPaint == null) { mPaint = new Paint() ; } } private void ensurePath(){ if (mPath == null) { mPath = new Path() ; } } private void initPaint() { ensurePaint(); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); mPaint.setStrokeWidth(3f); } public Bitmap getBitmap() { return mBitmap; } // 设置Bitmap的时候初始化shader,并设置给paint public void setBitmap(Bitmap bitmap) { this.mBitmap = bitmap; if (bitmap == null) { mShader =null ; } else { mShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP) ; mPaint.setShader(mShader) ; } } // 初始化好Path要走的路径 private void initPath() { ensurePath(); float l = (float) (mRect.width() / 2); float h = (float) (Math.sqrt(3)*l); float top = (mRect.height() - h) / 2 ; mPath.reset(); mPath.moveTo(l/2,top); mPath.lineTo(0,h/2+top); mPath.lineTo(l/2,h+top); mPath.lineTo((float) (l*1.5),h+top); mPath.lineTo(2*l,h/2+top); mPath.lineTo((float) (l*1.5),top); mPath.lineTo(l/2,top); mPath.close(); } @Override public void draw(Canvas canvas) { canvas.drawPath(mPath,mPaint); } @Override public void setAlpha(int alpha) { if (mPaint != null) { mPaint.setAlpha(alpha); } } @Override public void setColorFilter(ColorFilter colorFilter) { if (mPaint != null) { mPaint.setColorFilter(colorFilter) ; } } @Override public int getOpacity() { return 0 ; } // 设置边界信息 @Override public void setBounds(int left, int top, int right, int bottom) { super.setBounds(left, top, right, bottom); mRect.set(left, top, right, bottom); initPath(); } @Override public int getIntrinsicWidth() { if (mBitmap != null) { return mBitmap.getWidth(); } else { return super.getIntrinsicWidth() ; } } @Override public int getIntrinsicHeight() { if (mBitmap != null) { return mBitmap.getHeight() ; } return super.getIntrinsicHeight(); }
來源:简书
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2300
- 用户1336
- 访客10862077
每日一句
True success inspires others to act.
真正的成功是激励他人行动。
真正的成功是激励他人行动。
语法错误: 意外的令牌“标识符”
全面理解Gradle - 定义Task
Motrix全能下载工具 (支持 BT / 磁力链 / 百度网盘)
谷歌Pixel正在开始起飞?
获取ElementUI Table排序后的数据
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is
亲测!虚拟机VirtualBox安装MAC OS 10.12图文教程
华为手机app闪退重启界面清空log日志问题
android ndk开发之asm/page.h: not found
手机屏幕碎了怎么备份操作?
免ROOT实现模拟点击任意位置
新手必看修改DSDT教程
thinkpad t470p装黑苹果系统10.13.2
新会员