文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android中怎么通过自定义View实现圆形切图效果

2023-05-30 16:19

关注

本篇文章给大家分享的是有关Android中怎么通过自定义View实现圆形切图效果,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

实现思路

使用一个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; }


计算边距

  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,防止只显示图片边角

  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); }

完整代码

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(); }  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); }  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); }}

以上就是Android中怎么通过自定义View实现圆形切图效果,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯