• android 圆角 ImageView


    android中Imageview 内的图片圆角的实现方式

    此文针对的是 imageview中图片的圆角, 即忽略掉图片的ScaleType, 均对图片采取圆角.  而不是对Imageview本身的圆角.

    处理方式分两大类(暂不讨论具体的实现方式)

    1. 传入图片前将图片圆角化.
    2. 传入图片之后在绘制过程中进行圆角化处理.

    两种实现方式各有优劣.

      第一种实现方式在于每次调用之前需要对原图进行圆角化处理, 图片处理一般是比较耗时的操作(大图片比较明显), 而且处理完成后原图就本身带圆角, 不利于获取原来的图片, 此方法同时也是优势.....(无视那些保存原图的小伙伴.....)   

      第二种方式. 优势在于不需要对图片额外处理, 只需要执行正常的调用逻辑,  是在图片绘制中进行额外处理, 所以时间耗费比方法一少. 不过此种方法处理过的图形本身不带圆角, 只是显示中才有圆角. 而且此种方法实现过程中难点在于获取图片在imageview中的显示位置.

    方法二:  

      步骤一, 对图片的绘制过程进行控制, 需要计算出 imageview 中的图片的显示位置, 然后根据位置进行圆角绘制.

      根据imageview中图片的scaletype 不一样, 动态的计算图像在imageview中的位置.  核心代码如下

      

     1     private RectF genBounds() {
     2         RectF ret = new RectF(0, 0, 0, 0);
     3 
     4         if (getDrawable() == null) {
     5             return ret;
     6         }
     7 
     8         int dwidth = getDrawable().getIntrinsicWidth();
     9         int dheight = getDrawable().getIntrinsicHeight();
    10 
    11         int vwidth = getWidth() - getPaddingLeft() - getPaddingRight();
    12         int vheight = getHeight() - getPaddingTop() - getPaddingBottom();
    13 
    14         boolean fits = (dwidth < 0 || vwidth == dwidth) &&
    15                 (dheight < 0 || vheight == dheight);
    16 
    17         if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == getScaleType()) {
    18             ret.right = vwidth;
    19             ret.bottom = vheight;
    20         } else {
    21             ret = new RectF(0, 0, dwidth, dheight);
    22 
    23             if (ScaleType.MATRIX == getScaleType()) {
    24                 // Use the specified matrix as-is.
    25             } else if (fits) {
    26             } else if (ScaleType.CENTER == getScaleType()) {
    27                 ret.offset((int) ((vwidth - dwidth) * 0.5f + 0.5f),
    28                         (int) ((vheight - dheight) * 0.5f + 0.5f));
    29             } else if (ScaleType.CENTER_CROP == getScaleType()) {
    30 
    31                 float scale;
    32                 float dx = 0, dy = 0;
    33 
    34                 if (dwidth * vheight > vwidth * dheight) {
    35                     scale = (float) vheight / (float) dheight;
    36                     dx = (vwidth - dwidth * scale) * 0.5f;
    37                 } else {
    38                     scale = (float) vwidth / (float) dwidth;
    39                     dy = (vheight - dheight * scale) * 0.5f;
    40                 }
    41 
    42                 ret.offset((int) (dx + 0.5f), (int) (dy + 0.5f));
    43             } else if (ScaleType.CENTER_INSIDE == getScaleType()) {
    44                 float scale;
    45                 int dx;
    46                 int dy;
    47 
    48                 if (dwidth <= vwidth && dheight <= vheight) {
    49                     scale = 1.0f;
    50                 } else {
    51                     scale = Math.min((float) vwidth / (float) dwidth,
    52                             (float) vheight / (float) dheight);
    53                 }
    54 
    55                 dx = (int) ((vwidth - dwidth * scale) * 0.5f + 0.5f);
    56                 dy = (int) ((vheight - dheight * scale) * 0.5f + 0.5f);
    57 
    58                 ret.offset(dx, dy);
    59             }
    60         }
    61 
    62         if (ret.left < getPaddingLeft())
    63             ret.left = getPaddingLeft();
    64 
    65         if (ret.right > vwidth + getPaddingLeft())
    66             ret.right = vwidth + getPaddingLeft();
    67 
    68         if (ret.top < getPaddingTop()) ret.top = getPaddingTop();
    69 
    70         if (ret.bottom > vheight + getPaddingTop())
    71             ret.bottom = vheight + getPaddingTop();
    72 
    73         return ret;
    74     }

      步骤二: 对图片的绘制进行处理.

      

     1     private int cornerColor = Color.WHITE;
     2     private boolean usrRoundCorner = true;
     3     private Path mMaskPath = new Path();
     4 
     5     private void initPaint() {
     6         if (mPaint == null) {
     7             mPaint = new Paint();
     8             mPaint.setColor(getCornerColor());
     9             mPaint.setStrokeWidth(3);
    10             mPaint.setAntiAlias(true);
    11             mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    12         }
    13     }
    14 
    15     Paint mPaint;
    16     float mCornerRadius = getResources().getDisplayMetrics().density * 3 + 0.5f;
    17     float[] radii = new float[]{mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius, mCornerRadius};
    18 
    19     @Override
    20     protected void onDraw(Canvas canvas) {
    21         int saveCount = canvas.saveLayerAlpha(0F, 0F, canvas.getWidth(), canvas.getHeight(), 255, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
    22         super.onDraw(canvas);
    23 
    24         if (usrRoundCorner) {
    25             RectF bounds = genBounds();
    26 
    27             mMaskPath.reset();
    28             mMaskPath.addRoundRect(bounds, radii, Path.Direction.CW);
    29             mMaskPath.setFillType(Path.FillType.INVERSE_WINDING);
    30 
    31             canvas.drawPath(mMaskPath, mPaint);
    32         }
    33         canvas.restoreToCount(saveCount);
    34     }

    核心代码都在上面了.  大家有其他方法也可以留言告诉我.

    作者:闵天
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    函数式组件中的class与style处理
    学习CSS(二)
    mysql优化二
    mysql优化一
    spring解决循环依赖
    Java多线程2:Thread中的实例方法
    当try、catch中有return时,finally中的代码会执行么?
    Java多线程1:进程与线程
    手写springmvc
    手写spring
  • 原文地址:https://www.cnblogs.com/checkway/p/5133411.html
Copyright © 2020-2023  润新知