zl程序教程

您现在的位置是:首页 >  其它

当前栏目

自定义圆角和园边的实现

实现 自定义 圆角
2023-09-14 08:58:19 时间
p 本来想在网上找个圆角的例子看一看,不尽人意啊,基本都是官方的Demo的那张原理图,稍后会贴出。于是自己自定义了个View,实现图片的圆角以及圆形效果。效果图: /p p img src= http://img.blog.csdn.net/20140426213023062?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbG1qNjI
        paint.setAntiAlias(true);           Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);           /**           * 产生一个同样大小的画布           */           Canvas canvas = new Canvas(target);           /**           * 首先绘制圆形           */           canvas.drawCircle(min / 2, min / 2, min / 2, paint);           /**           * 使用SRC_IN           */           paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));           /**           * 绘制图片           */           canvas.drawBitmap(source, 0, 0, paint);           return target;       }  
其实主要靠:paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));这行代码,为什么呢,我给大家解释下,SRC_IN这种模式,两个绘制的效果叠加后取交集展现后图,怎么说呢,咱们第一个绘制的是个圆形,第二个绘制的是个Bitmap,于是交集为圆形,展现的是BItmap,就实现了圆形图片效果。圆角,其实就是先绘制圆角矩形,是不是很简单,以后别人再说实现圆角,你就把这一行代码给他就行了。

从Android的示例中,给大家证明一下:

下面有一张PorterDuff.Mode的16中效果图,咱们的只是其一:


源码咱们只关心谁先谁后绘制的:


              canvas.drawBitmap(mDstB, 0, 0, paint);                 paint.setXfermode(sModes[i]);                 canvas.drawBitmap(mSrcB, 0, 0, paint);                 paint.setXfermode(null);                 canvas.restoreToCount(sc);  
可以看出先绘制的Dst,再绘制的Src,最后的展示是SrcIn那个图:显示的区域是二者交集,展示的是Src(后者)。和咱们前面结论一致。效果16种,大家可以自由组合展示不同的效果。


好了,原理和核心代码解释完成。下面开始写自定义View。

1、自定义属性:


    TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyle, 0);       int n = a.getIndexCount();       for (int i = 0; i   i++)       {           int attr = a.getIndex(i);           switch (attr)           {           case R.styleable.CustomImageView_src:               mSrc = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));               break;           case R.styleable.CustomImageView_type:               type = a.getInt(attr, 0);// 默认为Circle               break;           case R.styleable.CustomImageView_borderRadius:               type = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10f,                       getResources().getDisplayMetrics()));// 默认为10DP               break;           }       }       a.recycle();  
    @Override       protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)       {           // super.onMeasure(widthMeasureSpec, heightMeasureSpec);           /**           * 设置宽度           */           int specMode = MeasureSpec.getMode(widthMeasureSpec);           int specSize = MeasureSpec.getSize(widthMeasureSpec);           if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate           {               mWidth = specSize;           } else           {               // 由图片决定的宽               int desireByImg = getPaddingLeft() + getPaddingRight() + mSrc.getWidth();               if (specMode == MeasureSpec.AT_MOST)// wrap_content               {                   mWidth = Math.min(desireByImg, specSize);               }           }           /***           * 设置高度           */           specMode = MeasureSpec.getMode(heightMeasureSpec);           specSize = MeasureSpec.getSize(heightMeasureSpec);           if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate           {               mHeight = specSize;           } else           {               int desire = getPaddingTop() + getPaddingBottom() + mSrc.getHeight();               if (specMode == MeasureSpec.AT_MOST)// wrap_content               {                   mHeight = Math.min(desire, specSize);               }           }           setMeasuredDimension(mWidth, mHeight);       }  
             */               mSrc = Bitmap.createScaledBitmap(mSrc, min, min, false);               canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);               break;           case TYPE_ROUND:               canvas.drawBitmap(createRoundConerImage(mSrc), 0, 0, null);               break;           }       }       /**       * 根据原图和变长绘制圆形图片       *        * @param source       * @param min       * @return       */       private Bitmap createCircleImage(Bitmap source, int min)       {           final Paint paint = new Paint();           paint.setAntiAlias(true);           Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);           /**           * 产生一个同样大小的画布           */           Canvas canvas = new Canvas(target);           /**           * 首先绘制圆形           */           canvas.drawCircle(min / 2, min / 2, min / 2, paint);           /**           * 使用SRC_IN,参考上面的说明           */           paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));           /**           * 绘制图片           */           canvas.drawBitmap(source, 0, 0, paint);           return target;       }       /**       * 根据原图添加圆角       *        * @param source       * @return       */       private Bitmap createRoundConerImage(Bitmap source)       {           final Paint paint = new Paint();           paint.setAntiAlias(true);           Bitmap target = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);           Canvas canvas = new Canvas(target);           RectF rect = new RectF(0, 0, source.getWidth(), source.getHeight());           canvas.drawRoundRect(rect, 50f, 50f, paint);           paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));           canvas.drawBitmap(source, 0, 0, paint);           return target;       }  
超简单的自定义ImageView,支持圆角和直角 需求:ImageView显示的图片,上方的两个角是圆角,下方的两个角是直角。 ![需求图](https://img-blog.csdn.net/20180125151146126?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMjYyODc0MzU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
如何新建shape文件:https://jingyan.baidu.com/article/b907e62795139746e7891cb9.html 如何在空间中加入shape.