当前位置: 移动技术网 > IT编程>移动开发>Android > Android自定义View实现圆形切图效果

Android自定义View实现圆形切图效果

2019年07月24日  | 移动技术网IT编程  | 我要评论

全影网,付首一,省委书记名单

使用自定义view实现圆形imageview的效果,具体内容如下

目前圆形边框还需要调整,这里有点问题

实现思路

使用一个paint,将得到的bitmap设置成paint的shader,设置完成后,使用matrix调整图片至居中,使用rectf约束边框,最后完成绘制

初始化paint,设置shader

private void init() {
  getbitmapfromdrawable();
  if (mbitmap == null) {
   return;
  }
  mshader = new bitmapshader(mbitmap, shader.tilemode.clamp, shader.tilemode.clamp);

  // bitmap paint
  mfillpaint = new paint();
  mfillpaint.setantialias(true);
  mfillpaint.setstyle(paint.style.fill);
  mfillpaint.setshader(mshader);

  // border paint
  mboundpaint = new paint();
  mboundpaint.setantialias(true);
  mboundpaint.setstyle(paint.style.stroke);
  mboundpaint.setstrokewidth(mborderwidth);
  mboundpaint.setcolor(mbordercolor);

  // border rectf
  mborderbound.set(calculatebitmapbound());

  // bitmap rectf
  mbitmapbound.set(calculatebitmapbound());
  mbitmapbound.inset(mborderwidth - 10, mborderwidth - 10);
  updateshadermatrix();

 }

获取drawable

private bitmap getbitmapfromdrawable() {
  drawable drawable = getdrawable();
  if (drawable instanceof bitmapdrawable) {
   mbitmap = ((bitmapdrawable) drawable).getbitmap();
   mbitmapwidth = mbitmap.getwidth();
   mbitmapheight = mbitmap.getheight();
   return mbitmap;
  }
  return null;
 }


计算边距

 /**
  * 计算bitmap边距
  */
 private rectf calculatebitmapbound() {
  int availablewidth = getwidth() - getpaddingleft() - getpaddingright();
  int availableheight = getheight() - getpaddingtop() - getpaddingbottom();
  int sidelength = math.min(availablewidth, availableheight); // 可用的直径
  mradius = sidelength / 2;

  int left = getpaddingleft() + (availablewidth - sidelength) / 2;
  int top = getpaddingtop() + (availableheight - sidelength) / 2;

  log.d(tag, "calculatebitmapbound: left >>> " + left + " top >>> " + top + " right >>> "
    + (left + sidelength) + " right >>> " + top + " bottom >>> " + (top + sidelength));
  return new rectf(left, top, left + sidelength, top + sidelength);
 }


调整matrix,防止只显示图片边角

 /**
  * 调整图片缩放,目前只支持centercrop
  */
 private void updateshadermatrix() {
  float scale;
  float dx = 0;
  float dy = 0;

  mshadermatrix.set(null);

  // 调整缩放,使图片居中
  if (mbitmapwidth * mbitmapbound.height() > mbitmapbound.width() * mbitmapheight) {
   scale = mbitmapbound.height() / (float) mbitmapheight;
   dx = (mbitmapbound.width() - mbitmapwidth * scale) * 0.5f;
  } else {
   scale = mbitmapbound.width() / (float) mbitmapwidth;
   dy = (mbitmapbound.height() - mbitmapheight * scale) * 0.5f;
  }

  log.d(tag, "updateshadermatrix: scale >>> " + scale);
  mshadermatrix.setscale(scale, scale);
  // todo: 16-10-15 http://chroya.iteye.com/blog/713869
  // 回到中心点,便于下次缩放
  mshadermatrix.posttranslate((int) (dx + 0.5f) + mbitmapbound.left, (int) (dy + 0.5f) + mbitmapbound.top);

  mshader.setlocalmatrix(mshadermatrix);
 }

ondraw

 @override
 protected void ondraw(canvas canvas) {
  if (mbitmap == null) {
   super.ondraw(canvas);
  }
  log.d(tag, "ondraw: centerx >>> " + mbitmapbound.centerx() + " centery >>> " + mbitmapbound.centery());
  canvas.drawcircle(mbitmapbound.centerx(), mbitmapbound.centery(), mradius, mfillpaint);
  // 绘制边框
  canvas.drawcircle(mborderbound.centerx(), mborderbound.centery(), mradius, mboundpaint);
 }


完整代码

/**
 * created by shixi_tianrui1 on 16-10-7.
 * 显示圆形图片的imageview
 */

public class circleimageview extends imageview {

 private static final string tag = "logger";

 private bitmapshader mshader;
 private paint mfillpaint; // 绘图
 private paint mboundpaint; // 绘制圆边

 private bitmap mbitmap;
 private drawable mdrawable;

 private int mbordercolor;  // 边框颜色
 private float mborderwidth;  // 边框宽度

 private rectf mborderbound = new rectf();
 private rectf mbitmapbound = new rectf();
 private matrix mshadermatrix = new matrix();

 private int mradius;
 private int mbitmapwidth;
 private int mbitmapheight;

 private static final float default_border_width = 5;

 public circleimageview(context context) {
  this(context, null);
 }

 public circleimageview(context context, attributeset attrs) {
  this(context, attrs, 0);
 }

 public circleimageview(context context, attributeset attrs, int defstyleattr) {
  super(context, attrs, defstyleattr);
  typedarray a = getresources().obtainattributes(attrs, r.styleable.circleimageview);
  mbordercolor = a.getcolor(r.styleable.circleimageview_bordercolor, color.blue);
  mborderwidth = a.getdimension(r.styleable.circleimageview_borderwidth, default_border_width);
  mborderwidth = a.getdimensionpixelsize(r.styleable.circleimageview_borderwidth, 20);
  a.recycle();
 }

 private void init() {
  getbitmapfromdrawable();
  if (mbitmap == null) {
   return;
  }
  mshader = new bitmapshader(mbitmap, shader.tilemode.clamp, shader.tilemode.clamp);

  // bitmap paint
  mfillpaint = new paint();
  mfillpaint.setantialias(true);
  mfillpaint.setstyle(paint.style.fill);
  mfillpaint.setshader(mshader);

  // border paint
  mboundpaint = new paint();
  mboundpaint.setantialias(true);
  mboundpaint.setstyle(paint.style.stroke);
  mboundpaint.setstrokewidth(mborderwidth);
  mboundpaint.setcolor(mbordercolor);

  // border rectf
  mborderbound.set(calculatebitmapbound());

  // bitmap rectf
  mbitmapbound.set(calculatebitmapbound());
  mbitmapbound.inset(mborderwidth - 10, mborderwidth - 10);
  updateshadermatrix();

 }

 @override
 protected void onsizechanged(int w, int h, int oldw, int oldh) {
  super.onsizechanged(w, h, oldw, oldh);
  init();
 }

 /**
  * 计算bitmap边距
  */
 private rectf calculatebitmapbound() {
  int availablewidth = getwidth() - getpaddingleft() - getpaddingright();
  int availableheight = getheight() - getpaddingtop() - getpaddingbottom();
  int sidelength = math.min(availablewidth, availableheight); // 可用的直径
  mradius = sidelength / 2;

  int left = getpaddingleft() + (availablewidth - sidelength) / 2;
  int top = getpaddingtop() + (availableheight - sidelength) / 2;

  log.d(tag, "calculatebitmapbound: left >>> " + left + " top >>> " + top + " right >>> "
    + (left + sidelength) + " right >>> " + top + " bottom >>> " + (top + sidelength));
  return new rectf(left, top, left + sidelength, top + sidelength);
 }


 private bitmap getbitmapfromdrawable() {
  drawable drawable = getdrawable();
  if (drawable instanceof bitmapdrawable) {
   mbitmap = ((bitmapdrawable) drawable).getbitmap();
   mbitmapwidth = mbitmap.getwidth();
   mbitmapheight = mbitmap.getheight();
   return mbitmap;
  }
  return null;
 }

 @override
 protected void ondraw(canvas canvas) {
  if (mbitmap == null) {
   super.ondraw(canvas);
  }
  log.d(tag, "ondraw: centerx >>> " + mbitmapbound.centerx() + " centery >>> " + mbitmapbound.centery());
  canvas.drawcircle(mbitmapbound.centerx(), mbitmapbound.centery(), mradius, mfillpaint);
  // 绘制边框
  canvas.drawcircle(mborderbound.centerx(), mborderbound.centery(), mradius, mboundpaint);
 }


 /**
  * 调整图片缩放,目前只支持centercrop
  */
 private void updateshadermatrix() {
  float scale;
  float dx = 0;
  float dy = 0;

  mshadermatrix.set(null);

  // 调整缩放,使图片居中
  if (mbitmapwidth * mbitmapbound.height() > mbitmapbound.width() * mbitmapheight) {
   scale = mbitmapbound.height() / (float) mbitmapheight;
   dx = (mbitmapbound.width() - mbitmapwidth * scale) * 0.5f;
  } else {
   scale = mbitmapbound.width() / (float) mbitmapwidth;
   dy = (mbitmapbound.height() - mbitmapheight * scale) * 0.5f;
  }

  log.d(tag, "updateshadermatrix: scale >>> " + scale);
  mshadermatrix.setscale(scale, scale);
  // todo: 16-10-15 http://chroya.iteye.com/blog/713869
  // 回到中心点,便于下次缩放
  mshadermatrix.posttranslate((int) (dx + 0.5f) + mbitmapbound.left, (int) (dy + 0.5f) + mbitmapbound.top);

  mshader.setlocalmatrix(mshadermatrix);
 }
}

目前仍有点问题,解决后会及时更新。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网