位置: 编程技术 - 正文

Android 圆形/圆角图片的方法(安卓圆角矩形图标)

编辑:rootadmin

推荐整理分享Android 圆形/圆角图片的方法(安卓圆角矩形图标),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:android设置圆角布局,android 圆角imageview,androiddialog圆角,androiddialog圆角,androiddialog圆角,android圆角图片,androiddialog圆角,androiddialog圆角,内容如对您有帮助,希望把文章链接给更多的朋友!

Android 圆形/圆角图片的方法

目前网上有很多圆角图片的实例,Github上也有一些成熟的项目。之前做项目,为了稳定高效都是选用Github上的项目直接用。但这种结束也是Android开发必备技能 ,所以今天就来简单研究一下该技术,分享给大家。

预备知识:

Xfermode介绍:

下面是Android ApiDemo里的“Xfermodes”实例,效果图。

Xfermode有三个子类,结构如下:

view sourceprint?1.publicclass2.Xfermode3.extendsObject4.java.lang.Object5.? android.graphics.Xfermode6.Known Direct Subclasses7.AvoidXfermode, PixelXorXfermode, PorterDuffXfermode

AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。

PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素异或操作。

PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。

上面图片种显示的种模式介绍如下:

1.PorterDuff.Mode.CLEAR

所绘制不会提交到画布上。2.PorterDuff.Mode.SRC

显示上层绘制图片3.PorterDuff.Mode.DST

显示下层绘制图片4.PorterDuff.Mode.SRC_OVER

正常绘制显示,上下层绘制叠盖。5.PorterDuff.Mode.DST_OVER

上下层都显示。下层居上显示。6.PorterDuff.Mode.SRC_IN

取两层绘制交集。显示上层。7.PorterDuff.Mode.DST_IN

取两层绘制交集。显示下层。8.PorterDuff.Mode.SRC_OUT

取上层绘制非交集部分。9.PorterDuff.Mode.DST_OUT

取下层绘制非交集部分。.PorterDuff.Mode.SRC_ATOP

取下层非交集部分与上层交集部分.PorterDuff.Mode.DST_ATOP

取上层非交集部分与下层交集部分.PorterDuff.Mode.XOR

异或:去除两图层交集部分.PorterDuff.Mode.DARKEN

Android 圆形/圆角图片的方法(安卓圆角矩形图标)

取两图层全部区域,交集部分颜色加深.PorterDuff.Mode.LIGHTEN

取两图层全部,点亮交集部分颜色.PorterDuff.Mode.MULTIPLY

取两图层交集部分叠加后颜色.PorterDuff.Mode.SCREEN

取两图层全部区域,交集部分变为透明色

了解了上面的知识点后,我们根据上面的知识点先来实现第一种圆角图片制作方式:

原图:

先看这一段代码

view sourceprint?.privateImageView mImg;. .@Override.protectedvoid onCreate(Bundle savedInstanceState) {.super.onCreate(savedInstanceState);.setContentView(R.layout.activity_main);.mImg = (ImageView) findViewById(R.id.img);. .//获得imageview中设置的图片.BitmapDrawable drawable = (BitmapDrawable) mImg.getDrawable();.Bitmap bmp = drawable.getBitmap();.//获得图片的宽,并创建结果bitmap.intwidth = bmp.getWidth();.Bitmap resultBmp = Bitmap.createBitmap(width, width,.Bitmap.Config.ARGB_);.Paint paint =new Paint();.Canvas canvas =new Canvas(resultBmp);.//画圆.canvas.drawCircle(width /2, width / 2, width /2, paint);.paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.SRC_IN));// 选择交集去上层图片.canvas.drawBitmap(bmp,0, 0, paint);.mImg.setImageBitmap(resultBmp);.bmp.recycle();. .}通过运行上面的代码,我们得出的结果如下:

大家看到这是我们需要的结果。可是这样做可能导致OutOfMomery异常。假如图片很大或者你可能并非通过ImageView的getDrawable获得图像,而是直接Decode一张很大的图片加载到内存,你会发现可能会出现异常。我们做一下改变。

view sourceprint?.privatestatic final String TAG = "RoundImage";.privateImageView mImg;. .@Override.protectedvoid onCreate(Bundle savedInstanceState) {.super.onCreate(savedInstanceState);.setContentView(R.layout.activity_main);.mImg = (ImageView) findViewById(R.id.img);.// 裁剪图片.BitmapFactory.Options options =new BitmapFactory.Options();.options.inJustDecodeBounds =true;.BitmapFactory..decodeResource(getResources(), R.drawable.avatar, options);.Log.d(TAG,"original outwidth: " &#; options.outWidth);.// 此宽度是目标ImageView希望的大小,你可以自定义ImageView,然后获得ImageView的宽度。.intdstWidth = ;.// 我们需要加载的图片可能很大,我们先对原有的图片进行裁剪.intsampleSize = calculateInSampleSize(options, dstWidth, dstWidth);.options.inSampleSize = sampleSize;.options.inJustDecodeBounds =false;.Log.d(TAG,"sample size: " &#; sampleSize);.Bitmap bmp = BitmapFactory.decodeResource(getResources(),.R.drawable.avatar, options);. .// 绘制图片.Bitmap resultBmp = Bitmap.createBitmap(dstWidth, dstWidth,.Bitmap.Config.ARGB_);.Paint paint =new Paint();.paint.setAntiAlias(true);.Canvas canvas =new Canvas(resultBmp);.// 画圆.canvas.drawCircle(dstWidth /2, dstWidth / 2, dstWidth /2, paint);.// 选择交集去上层图片.paint.setXfermode(newPorterDuffXfermode(PorterDuff.Mode.SRC_IN));.canvas.drawBitmap(bmp,new Rect(0,0, bmp.getWidth(), bmp.getWidth()),.newRect(0,0, dstWidth, dstWidth), paint);.mImg.setImageBitmap(resultBmp);.bmp.recycle();.}. .privateint calculateInSampleSize(BitmapFactory.Options options,.intreqWidth, int reqHeight) {.// Raw height and width of image.finalint height = options.outHeight;.finalint width = options.outWidth;.intinSampleSize = 1;. .if(height > reqHeight || width > reqWidth) {. .finalint halfHeight = height / 2;.finalint halfWidth = width / 2;. .// Calculate the largest inSampleSize value that is a power of 2 and.// keeps both.// height and width larger than the requested height and width..while((halfHeight / inSampleSize) > reqHeight.&& (halfWidth / inSampleSize) > reqWidth) {.inSampleSize *=2;.}.}.returninSampleSize;.}

再来看一下效果:

上面提供了一种方式,更多细节,需要你自己去优化,下面介绍第二种绘制圆角图片的方式。

首先我们需要了解一个类BitmapShader

引用的介绍如下:

public BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)

调用这个方法来产生一个画有一个位图的渲染器(Shader)。

bitmap 在渲染器内使用的位图

tileX The tiling mode for x to draw the bitmap in. 在位图上X方向花砖模式

tileY The tiling mode for y to draw the bitmap in. 在位图上Y方向花砖模式

TileMode:(一共有三种)

CLAMP :如果渲染器超出原始边界范围,会复制范围内边缘染色。

REPEAT :横向和纵向的重复渲染器图片,平铺。

MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT 重复方式不一样,他是以镜像方式平铺。

知道这个原理后,我们贴出对应的代码:view sourceprint?.publicclass CircleImageView extendsImageView {. .privatestatic final String TAG = CircleImageView.class.getSimpleName();.privatePaint mBitmapPaint = new Paint();.privateint mRadius;. .publicCircleImageView(Context context, AttributeSet attrs, intdefStyleAttr) {.super(context, attrs, defStyleAttr);.init();.}. .publicCircleImageView(Context context, AttributeSet attrs) {.super(context, attrs);.init();.}. .publicCircleImageView(Context context) {.super(context);.init();.}. .privatevoid init() {.BitmapDrawable drawable = (BitmapDrawable) getDrawable();.if(drawable == null) {.Log.i(TAG,"drawable: null");.return;.}.Bitmap bmp = drawable.getBitmap();.BitmapShader shader =new BitmapShader(bmp, TileMode.CLAMP,.TileMode.CLAMP);.mBitmapPaint.setShader(shader);.mBitmapPaint.setAntiAlias(true);.invalidate();.}. .@Override.protectedvoid onDraw(Canvas canvas) {.if(getDrawable() == null) {.return;.}.mRadius = Math.min(getWidth()/2, getHeight()/2);.canvas.drawCircle(getWidth() /2, getHeight() / 2, mRadius,.mBitmapPaint);.}. .}

是不是挺简单的

结果我就不显示了,跟上面的一样。上面也是最原始的代码,文章的结尾贴出一份完整优化过的代码共大家参考如下:

view sourceprint?.publicclass CircleImageView extendsImageView {. .privatestatic final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;. .privatestatic final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_;.privatestatic final int COLORDRAWABLE_DIMENSION = 1;. .privatestatic final int DEFAULT_BORDER_WIDTH = 0;.privatestatic final int DEFAULT_BORDER_COLOR = Color.BLACK;. .privatefinal RectF mDrawableRect = new RectF();.privatefinal RectF mBorderRect = new RectF();. .privatefinal Matrix mShaderMatrix = new Matrix();.privatefinal Paint mBitmapPaint = new Paint();.privatefinal Paint mBorderPaint = new Paint();. .privateint mBorderColor = DEFAULT_BORDER_COLOR;.privateint mBorderWidth = DEFAULT_BORDER_WIDTH;. .privateBitmap mBitmap;.privateBitmapShader mBitmapShader;.privateint mBitmapWidth;.privateint mBitmapHeight;. .privatefloat mDrawableRadius;.privatefloat mBorderRadius;. .privateboolean mReady;.privateboolean mSetupPending;. .publicCircleImageView(Context context) {.super(context);. .init();.}. .publicCircleImageView(Context context, AttributeSet attrs) {.this(context, attrs,0);.}. .publicCircleImageView(Context context, AttributeSet attrs, intdefStyle) {.super(context, attrs, defStyle);. .TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle,0);. .mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);.mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);. .a.recycle();. .init();.}. .privatevoid init() {.super.setScaleType(SCALE_TYPE);.mReady =true;. .if(mSetupPending) {.setup();.mSetupPending =false;.}.}. .@Override.publicScaleType getScaleType() {.returnSCALE_TYPE;.}. .@Override.publicvoid setScaleType(ScaleType scaleType) {.if(scaleType != SCALE_TYPE) {.thrownew IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));.}.}. .@Override.protectedvoid onDraw(Canvas canvas) {.if(getDrawable() == null) {.return;.}. .canvas.drawCircle(getWidth() /2, getHeight() / 2, mDrawableRadius, mBitmapPaint);.if(mBorderWidth != 0) {.canvas.drawCircle(getWidth() /2, getHeight() / 2, mBorderRadius, mBorderPaint);.}.}. .@Override.protectedvoid onSizeChanged(intw, int h, int oldw, intoldh) {.super.onSizeChanged(w, h, oldw, oldh);.setup();.}. .publicint getBorderColor() {.returnmBorderColor;.}. .publicvoid setBorderColor(intborderColor) {.if(borderColor == mBorderColor) {.return;.}. .mBorderColor = borderColor;.mBorderPaint.setColor(mBorderColor);.invalidate();.}. .publicint getBorderWidth() {.returnmBorderWidth;.}. .publicvoid setBorderWidth(intborderWidth) {.if(borderWidth == mBorderWidth) {.return;.}. .mBorderWidth = borderWidth;.setup();.}. .@Override.publicvoid setImageBitmap(Bitmap bm) {.super.setImageBitmap(bm);.mBitmap = bm;.setup();.}. .@Override.publicvoid setImageDrawable(Drawable drawable) {.super.setImageDrawable(drawable);.mBitmap = getBitmapFromDrawable(drawable);.setup();.}. .@Override.publicvoid setImageResource(intresId) {.super.setImageResource(resId);.mBitmap = getBitmapFromDrawable(getDrawable());.setup();.}. .@Override.publicvoid setImageURI(Uri uri) {.super.setImageURI(uri);.mBitmap = getBitmapFromDrawable(getDrawable());.setup();.}. .privateBitmap getBitmapFromDrawable(Drawable drawable) {.if(drawable == null) {.returnnull;.}. .if(drawable instanceof BitmapDrawable) {.return((BitmapDrawable) drawable).getBitmap();.}. .try{.Bitmap bitmap;. .if(drawable instanceof ColorDrawable) {.bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);.}else {.bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);.}. .Canvas canvas =new Canvas(bitmap);.drawable.setBounds(0,0, canvas.getWidth(), canvas.getHeight());.drawable.draw(canvas);.returnbitmap;.}catch (OutOfMemoryError e) {.returnnull;.}.}. .privatevoid setup() {.if(!mReady) {.mSetupPending =true;.return;.}. .if(mBitmap == null) {.return;.}. .mBitmapShader =new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);. .mBitmapPaint.setAntiAlias(true);.mBitmapPaint.setShader(mBitmapShader);. .mBorderPaint.setStyle(Paint.Style.STROKE);.mBorderPaint.setAntiAlias(true);.mBorderPaint.setColor(mBorderColor);.mBorderPaint.setStrokeWidth(mBorderWidth);. .mBitmapHeight = mBitmap.getHeight();.mBitmapWidth = mBitmap.getWidth();. .mBorderRect.set(0,0, getWidth(), getHeight());.mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) /2, (mBorderRect.width() - mBorderWidth) /2);. .mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width() - mBorderWidth, mBorderRect.height() - mBorderWidth);.mDrawableRadius = Math.min(mDrawableRect.height() /2, mDrawableRect.width() / 2);. .updateShaderMatrix();.invalidate();.}. .privatevoid updateShaderMatrix() {.floatscale;.floatdx = 0;.floatdy = 0;. .mShaderMatrix.set(null);. .if(mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {.scale = mDrawableRect.height() / (float) mBitmapHeight;.dx = (mDrawableRect.width() - mBitmapWidth * scale) *0.5f;.}else {.scale = mDrawableRect.width() / (float) mBitmapWidth;.dy = (mDrawableRect.height() - mBitmapHeight * scale) *0.5f;.}. .mShaderMatrix.setScale(scale, scale);.mShaderMatrix.postTranslate((int) (dx &#;0.5f) &#; mBorderWidth, (int) (dy &#;0.5f) &#; mBorderWidth);. .mBitmapShader.setLocalMatrix(mShaderMatrix);.}. .}

CentOS使用android 一,Linux部署JDK1.1下载JDK地址:

android 背景图片的变形(background) 这是我因为这个问题第二次影响开发效果了,第一次遇到时解决了一下,中间也遇到过它,都给解决了,但是一段时间后遗忘了,现在把它记下:对butto

android开发扩大CheckBox点击监听范围 android开发过程中,image很小的时候,点击范围很小,很难点击到,用户体验差,在xml文件添加android:text=,就是空格。android:drawableRight="@drawable/...."android:

标签: 安卓圆角矩形图标

本文链接地址:https://www.jiuchutong.com/biancheng/385098.html 转载请保留说明!

上一篇:Android Studio --自动删除没有用的资源,给APK减减肥

下一篇:CentOS使用android(安卓 centos)

  • 企业所得税研发费用加计扣除条件
  • 销售货物的运费计入成本吗
  • 公司出售房产缴纳税金如何凭证
  • 建筑企业简易计税和一般计税分开核算
  • 小规模纳税人减征额怎么计算
  • 残保金滞纳金能抵扣吗
  • 坏账准备的会计分录怎么写例题
  • 增值税不允许抵扣的27种情况
  • 收付转记凭证如何填写例题
  • 总账期末余额为零怎么写
  • 非独立核算的公司怎么报税
  • 一般纳税人花椒税率
  • 通讯费计入什么部门
  • 借款利息不能抵扣进项税
  • 退税入其他收益需要再缴税吗
  • 可以税前扣除的收据有哪些
  • 向购买方收取的价外费用
  • 企业收到固定资产投资时应按什么入账
  • 工程施工纳税
  • 预缴企业所得税额怎么算
  • 公司如何确定总股本
  • 收款收据怎么写 样本
  • 全资子公司合并抵消
  • 自行研发的专利权计入
  • 内账增值税会计核算
  • 怎样才能防止臭虫在卧室里呢
  • 对方已经认证的红字发票怎么开
  • 存贷款利率计算器
  • 入库单的金额填不填价税合计
  • 怎么找回windows图片查看器
  • type3插件
  • 电脑上一键复制是哪个键
  • 增值税出口服务包括什么
  • 农产品核定扣除的扣除率是多少
  • php根据日期判断星座
  • 政府补助财务处理流程
  • 运费发票如何入账
  • php set_time_limit
  • 蛇形矩阵找数的位置
  • php怎么输出文字
  • 电费打发票用哪个软件
  • 工具tj
  • js中reduce用法
  • 网络模型参数方法
  • 外国人在中国工作签证
  • 年终奖是以工资形式发放吗
  • 月末损益结转手工结转步骤
  • 购进固定资产的进项税计入成本吗
  • 年终奖怎么计算个税
  • 低值易耗品如何摊销
  • 现金日记账年结怎么做
  • 从事国家重点扶持的公共基础项目
  • 资产收购一般税务处理
  • 企业因固定资产破产
  • 递延所得税与递延所得税费用
  • 哪些资产减值损失确认过后是可以转回的
  • sql返回数据条数
  • jmeter怎么连接数据库
  • mysql免安装版怎么启动
  • ubuntu系统中安装微信步骤
  • windows7窗口拖到屏幕顶端
  • linux 截屏
  • windows 7安装步骤
  • Cocos2dx------从json文件读取数据
  • jquery怎么获取
  • node connect
  • jQuery javascript获得网页的高度与宽度的实现代码
  • angular nz
  • js中的常用方法
  • js中文本框设置的代码
  • js实现表格动态合并单元格
  • bootstrap学习
  • android开发流程
  • 如何理解python语言
  • 沈阳地方税务局原局长
  • 个人进口关税税率
  • 柜台申报税务流程图
  • 不明身份人员法律定义?
  • 建设工程造价咨询合同需要交印花税吗
  • 山西税务体检医院
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设