开发中我们经常在显示图片相关需求的时候需要加载圆角图片,下面几种方式来实现图片的圆角化。

1:第一种方式是本人比较推荐的,直接在需要加载的图片外部嵌套一层CardView控件来实现图片

的圆角化,因为写起来简单,而且在项目中可以使用第三方开源库如Glide,ImageLoader等来加载动态图之类的

不会出现什么问题,如果使用第3种方式来实现的话就很容易出问题。

<android.support.v7.widget.CardViewandroid:id="@+id/img_item_card"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:layout_marginBottom="8dp"android:layout_marginRight="12dp"app:cardCornerRadius="4dp"app:cardElevation="0dp"><ImageViewandroid:id="@+id/img_item_images"android:layout_width="110dp"android:layout_height="69dp"android:scaleType="fitXY"/>
</android.support.v7.widget.CardView>

这种方式比较简单直接。

2:类似于第一种方式,在ImageView的布局外嵌套一层ViewGroup来实现,比如

    <LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_centerInParent="true"android:background="@drawable/bg_dialog_prompt"android:orientation="vertical" ><ImageViewandroid:id="@+id/img_item_images"android:layout_width="110dp"android:layout_height="69dp"android:scaleType="fitXY"app:srcCompat="@drawable/ic_placeholder"/></LinearLayout>

其中外层的LinearLayout的背景填充bg_dialog_prompt.xml文件代码为:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" ><corners android:radius="10dp" /><gradientandroid:endColor="#ffffff"android:startColor="#ffffff" /></shape>

这种方式也可以实现图片的圆角化。

3:直接定义自己的ImageView继承ImageView来实现:

public class RoundedImageView extends AppCompatImageView {// Constants for tile mode attributesprivate static final int TILE_MODE_UNDEFINED = -2;private static final int TILE_MODE_CLAMP = 0;private static final int TILE_MODE_REPEAT = 1;private static final int TILE_MODE_MIRROR = 2;public static final String TAG = "RoundedImageView";public static final float DEFAULT_RADIUS = 0f;public static final float DEFAULT_BORDER_WIDTH = 0f;public static final Shader.TileMode DEFAULT_TILE_MODE = Shader.TileMode.CLAMP;private static final ScaleType[] SCALE_TYPES = {ScaleType.MATRIX,ScaleType.FIT_XY,ScaleType.FIT_START,ScaleType.FIT_CENTER,ScaleType.FIT_END,ScaleType.CENTER,ScaleType.CENTER_CROP,ScaleType.CENTER_INSIDE};private final float[] mCornerRadii =new float[] { DEFAULT_RADIUS, DEFAULT_RADIUS, DEFAULT_RADIUS, DEFAULT_RADIUS };private Drawable mBackgroundDrawable;private ColorStateList mBorderColor =ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);private float mBorderWidth = DEFAULT_BORDER_WIDTH;private ColorFilter mColorFilter = null;private boolean mColorMod = false;private Drawable mDrawable;private boolean mHasColorFilter = false;private boolean mIsOval = false;private boolean mMutateBackground = false;private int mResource;private int mBackgroundResource;private ScaleType mScaleType;private Shader.TileMode mTileModeX = DEFAULT_TILE_MODE;private Shader.TileMode mTileModeY = DEFAULT_TILE_MODE;public RoundedImageView(Context context) {super(context);}public RoundedImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public RoundedImageView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageView, defStyle, 0);int index = a.getInt(R.styleable.RoundedImageView_android_scaleType, -1);if (index >= 0) {setScaleType(SCALE_TYPES[index]);} else {// default scaletype to FIT_CENTERsetScaleType(ScaleType.FIT_CENTER);}float cornerRadiusOverride =a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius, -1);mCornerRadii[Corner.TOP_LEFT] =a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_top_left, -1);mCornerRadii[Corner.TOP_RIGHT] =a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_top_right, -1);mCornerRadii[Corner.BOTTOM_RIGHT] =a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_bottom_right, -1);mCornerRadii[Corner.BOTTOM_LEFT] =a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_corner_radius_bottom_left, -1);boolean any = false;for (int i = 0, len = mCornerRadii.length; i < len; i++) {if (mCornerRadii[i] < 0) {mCornerRadii[i] = 0f;} else {any = true;}}if (!any) {if (cornerRadiusOverride < 0) {cornerRadiusOverride = DEFAULT_RADIUS;}for (int i = 0, len = mCornerRadii.length; i < len; i++) {mCornerRadii[i] = cornerRadiusOverride;}}mBorderWidth = a.getDimensionPixelSize(R.styleable.RoundedImageView_riv_border_width, -1);if (mBorderWidth < 0) {mBorderWidth = DEFAULT_BORDER_WIDTH;}mBorderColor = a.getColorStateList(R.styleable.RoundedImageView_riv_border_color);if (mBorderColor == null) {mBorderColor = ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);}mMutateBackground = a.getBoolean(R.styleable.RoundedImageView_riv_mutate_background, false);mIsOval = a.getBoolean(R.styleable.RoundedImageView_riv_oval, false);final int tileMode = a.getInt(R.styleable.RoundedImageView_riv_tile_mode, TILE_MODE_UNDEFINED);if (tileMode != TILE_MODE_UNDEFINED) {setTileModeX(parseTileMode(tileMode));setTileModeY(parseTileMode(tileMode));}final int tileModeX =a.getInt(R.styleable.RoundedImageView_riv_tile_mode_x, TILE_MODE_UNDEFINED);if (tileModeX != TILE_MODE_UNDEFINED) {setTileModeX(parseTileMode(tileModeX));}final int tileModeY =a.getInt(R.styleable.RoundedImageView_riv_tile_mode_y, TILE_MODE_UNDEFINED);if (tileModeY != TILE_MODE_UNDEFINED) {setTileModeY(parseTileMode(tileModeY));}updateDrawableAttrs();updateBackgroundDrawableAttrs(true);if (mMutateBackground) {// when setBackground() is called by View constructor, mMutateBackground is not loaded from the attribute,// so it's false by default, what doesn't allow to create the RoundedDrawable. At this point, after load// mMutateBackground and updated BackgroundDrawable to RoundedDrawable, the View's background drawable needs to// be changed to this new drawable.//noinspection deprecationsuper.setBackgroundDrawable(mBackgroundDrawable);}a.recycle();}private static Shader.TileMode parseTileMode(int tileMode) {switch (tileMode) {case TILE_MODE_CLAMP:return Shader.TileMode.CLAMP;case TILE_MODE_REPEAT:return Shader.TileMode.REPEAT;case TILE_MODE_MIRROR:return Shader.TileMode.MIRROR;default:return null;}}@Overrideprotected void drawableStateChanged() {super.drawableStateChanged();invalidate();}@Overridepublic ScaleType getScaleType() {return mScaleType;}@Overridepublic void setScaleType(ScaleType scaleType) {assert scaleType != null;if (mScaleType != scaleType) {mScaleType = scaleType;switch (scaleType) {case CENTER:case CENTER_CROP:case CENTER_INSIDE:case FIT_CENTER:case FIT_START:case FIT_END:case FIT_XY:super.setScaleType(ScaleType.FIT_XY);break;default:super.setScaleType(scaleType);break;}updateDrawableAttrs();updateBackgroundDrawableAttrs(false);invalidate();}}@Overridepublic void setImageDrawable(Drawable drawable) {mResource = 0;mDrawable = RoundedDrawable.fromDrawable(drawable);updateDrawableAttrs();super.setImageDrawable(mDrawable);}@Overridepublic void setImageBitmap(Bitmap bm) {mResource = 0;mDrawable = RoundedDrawable.fromBitmap(bm);updateDrawableAttrs();super.setImageDrawable(mDrawable);}@Overridepublic void setImageResource(@DrawableRes int resId) {if (mResource != resId) {mResource = resId;mDrawable = resolveResource();updateDrawableAttrs();super.setImageDrawable(mDrawable);}}@Override public void setImageURI(Uri uri) {super.setImageURI(uri);setImageDrawable(getDrawable());}private Drawable resolveResource() {Resources rsrc = getResources();if (rsrc == null) { return null; }Drawable d = null;if (mResource != 0) {try {d = rsrc.getDrawable(mResource);} catch (Exception e) {Logger.w(TAG, "Unable to find resource: " + mResource, e);// Don't try again.mResource = 0;}}return RoundedDrawable.fromDrawable(d);}@Overridepublic void setBackground(Drawable background) {setBackgroundDrawable(background);}@Overridepublic void setBackgroundResource(@DrawableRes int resId) {if (mBackgroundResource != resId) {mBackgroundResource = resId;mBackgroundDrawable = resolveBackgroundResource();setBackgroundDrawable(mBackgroundDrawable);}}@Overridepublic void setBackgroundColor(int color) {mBackgroundDrawable = new ColorDrawable(color);setBackgroundDrawable(mBackgroundDrawable);}private Drawable resolveBackgroundResource() {Resources rsrc = getResources();if (rsrc == null) { return null; }Drawable d = null;if (mBackgroundResource != 0) {try {d = rsrc.getDrawable(mBackgroundResource);} catch (Exception e) {Logger.w(TAG, "Unable to find resource: " + mBackgroundResource, e);// Don't try again.mBackgroundResource = 0;}}return RoundedDrawable.fromDrawable(d);}private void updateDrawableAttrs() {updateAttrs(mDrawable, mScaleType);}private void updateBackgroundDrawableAttrs(boolean convert) {if (mMutateBackground) {if (convert) {mBackgroundDrawable = RoundedDrawable.fromDrawable(mBackgroundDrawable);}updateAttrs(mBackgroundDrawable, ScaleType.FIT_XY);}}@Override public void setColorFilter(ColorFilter cf) {if (mColorFilter != cf) {mColorFilter = cf;mHasColorFilter = true;mColorMod = true;applyColorMod();invalidate();}}private void applyColorMod() {// Only mutate and apply when modifications have occurred. This should// not reset the mColorMod flag, since these filters need to be// re-applied if the Drawable is changed.if (mDrawable != null && mColorMod) {mDrawable = mDrawable.mutate();if (mHasColorFilter) {mDrawable.setColorFilter(mColorFilter);}// TODO: support, eventually...//mDrawable.setXfermode(mXfermode);//mDrawable.setAlpha(mAlpha * mViewAlphaScale >> 8);}}private void updateAttrs(Drawable drawable, ScaleType scaleType) {if (drawable == null) { return; }if (drawable instanceof RoundedDrawable) {((RoundedDrawable) drawable).setScaleType(scaleType).setBorderWidth(mBorderWidth).setBorderColor(mBorderColor).setOval(mIsOval).setTileModeX(mTileModeX).setTileModeY(mTileModeY);if (mCornerRadii != null) {((RoundedDrawable) drawable).setCornerRadius(mCornerRadii[Corner.TOP_LEFT],mCornerRadii[Corner.TOP_RIGHT],mCornerRadii[Corner.BOTTOM_RIGHT],mCornerRadii[Corner.BOTTOM_LEFT]);}applyColorMod();} else if (drawable instanceof LayerDrawable) {// loop through layers to and set drawable attrsLayerDrawable ld = ((LayerDrawable) drawable);for (int i = 0, layers = ld.getNumberOfLayers(); i < layers; i++) {updateAttrs(ld.getDrawable(i), scaleType);}}}@Override@Deprecatedpublic void setBackgroundDrawable(Drawable background) {mBackgroundDrawable = background;updateBackgroundDrawableAttrs(true);//noinspection deprecationsuper.setBackgroundDrawable(mBackgroundDrawable);}/*** @return the largest corner radius.*/public float getCornerRadius() {return getMaxCornerRadius();}/*** @return the largest corner radius.*/public float getMaxCornerRadius() {float maxRadius = 0;for (float r : mCornerRadii) {maxRadius = Math.max(r, maxRadius);}return maxRadius;}/*** Get the corner radius of a specified corner.** @param corner the corner.* @return the radius.*/public float getCornerRadius(@Corner int corner) {return mCornerRadii[corner];}/*** Set all the corner radii from a dimension resource id.** @param resId dimension resource id of radii.*/public void setCornerRadiusDimen(@DimenRes int resId) {float radius = getResources().getDimension(resId);setCornerRadius(radius, radius, radius, radius);}/*** Set the corner radius of a specific corner from a dimension resource id.** @param corner the corner to set.* @param resId the dimension resource id of the corner radius.*/public void setCornerRadiusDimen(@Corner int corner, @DimenRes int resId) {setCornerRadius(corner, getResources().getDimensionPixelSize(resId));}/*** Set the corner radii of all corners in px.** @param radius the radius to set.*/public void setCornerRadius(float radius) {setCornerRadius(radius, radius, radius, radius);}/*** Set the corner radius of a specific corner in px.** @param corner the corner to set.* @param radius the corner radius to set in px.*/public void setCornerRadius(@Corner int corner, float radius) {if (mCornerRadii[corner] == radius) {return;}mCornerRadii[corner] = radius;updateDrawableAttrs();updateBackgroundDrawableAttrs(false);invalidate();}/*** Set the corner radii of each corner individually. Currently only one unique nonzero value is* supported.** @param topLeft radius of the top left corner in px.* @param topRight radius of the top right corner in px.* @param bottomRight radius of the bottom right corner in px.* @param bottomLeft radius of the bottom left corner in px.*/public void setCornerRadius(float topLeft, float topRight, float bottomLeft, float bottomRight) {if (mCornerRadii[Corner.TOP_LEFT] == topLeft&& mCornerRadii[Corner.TOP_RIGHT] == topRight&& mCornerRadii[Corner.BOTTOM_RIGHT] == bottomRight&& mCornerRadii[Corner.BOTTOM_LEFT] == bottomLeft) {return;}mCornerRadii[Corner.TOP_LEFT] = topLeft;mCornerRadii[Corner.TOP_RIGHT] = topRight;mCornerRadii[Corner.BOTTOM_LEFT] = bottomLeft;mCornerRadii[Corner.BOTTOM_RIGHT] = bottomRight;updateDrawableAttrs();updateBackgroundDrawableAttrs(false);invalidate();}public float getBorderWidth() {return mBorderWidth;}public void setBorderWidth(@DimenRes int resId) {setBorderWidth(getResources().getDimension(resId));}public void setBorderWidth(float width) {if (mBorderWidth == width) { return; }mBorderWidth = width;updateDrawableAttrs();updateBackgroundDrawableAttrs(false);invalidate();}@ColorIntpublic int getBorderColor() {return mBorderColor.getDefaultColor();}public void setBorderColor(@ColorInt int color) {setBorderColor(ColorStateList.valueOf(color));}public ColorStateList getBorderColors() {return mBorderColor;}public void setBorderColor(ColorStateList colors) {if (mBorderColor.equals(colors)) { return; }mBorderColor =(colors != null) ? colors : ColorStateList.valueOf(RoundedDrawable.DEFAULT_BORDER_COLOR);updateDrawableAttrs();updateBackgroundDrawableAttrs(false);if (mBorderWidth > 0) {invalidate();}}public boolean isOval() {return mIsOval;}public void setOval(boolean oval) {mIsOval = oval;updateDrawableAttrs();updateBackgroundDrawableAttrs(false);invalidate();}public Shader.TileMode getTileModeX() {return mTileModeX;}public void setTileModeX(Shader.TileMode tileModeX) {if (this.mTileModeX == tileModeX) { return; }this.mTileModeX = tileModeX;updateDrawableAttrs();updateBackgroundDrawableAttrs(false);invalidate();}public Shader.TileMode getTileModeY() {return mTileModeY;}public void setTileModeY(Shader.TileMode tileModeY) {if (this.mTileModeY == tileModeY) { return; }this.mTileModeY = tileModeY;updateDrawableAttrs();updateBackgroundDrawableAttrs(false);invalidate();}public boolean mutatesBackground() {return mMutateBackground;}public void mutateBackground(boolean mutate) {if (mMutateBackground == mutate) { return; }mMutateBackground = mutate;updateBackgroundDrawableAttrs(true);invalidate();}
}

使用方式直接在布局中:

<com.xx.xxx.RoundedImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@android:color/transparent"android:scaleType="centerCrop"app:riv_border_color="@android:color/white"app:riv_border_width="1dp"app:riv_oval="false"app:riv_corner_radius="15dp"/>

Android中实现ImageView圆角化的几种 方式相关推荐

  1. android数据库侵入,Android中实现侵入式状态栏的两种方式

    最近对"爸比讲故事"Android版本进行代码重构的时候,对之前版本的大部分界面的头部侵入式效果,作了一个总结和梳理,在期间查阅了thinkcool的博客和结合亲身实践,总结了2种 ...

  2. android的xml解析方式,Android中对xml文件解析的3种方式总结

    前言 xml 是数据传输的一种格式,Android 中的布局文件.设置文件等都采用它来表示.Android 中对 xml 文件的解析也有多种方式,下面介绍常用的 3 种方式: Dom . SAX 和 ...

  3. android java调用_关于Android中Java调用外部命令的三种方式

    此所谓三种方式,只是个人认为.本人还是菜鸟初涉,所以有所错误,请指正. 个人认为,Java调用外部命令.无非三种情况: 一.是只执行命令,不考虑返回值. 二.是执行命令的同时,还需要得到返回值. 三. ...

  4. android模拟按键方法,Android随笔之——模拟按键操作的几种方式

    前几天转过一篇Android上模拟按键操作.触屏事件的博客,昨天又去找了百度.谷歌了一下,写了一点简单的测试代码,留待不时之需.有需要看之前转载的那篇博客的请看这里→_→转:Android随笔之--使 ...

  5. android中的ImageView,ImageView加载网络图片

    android中的ImageView,ImageView加载网路图片 在布局文件中加入标签

  6. android启动其他app的服务器,Android中通过外部程序启动App的三种方法

    这篇文章主要介绍了Android中通过外部程序启动App的三种方法, 本文讲解了直接通过包名. 通过自定义的Action. 通过Scheme三种方法,并分别给出操作代码,需要的朋友可以参考下 ==== ...

  7. Android中监听Home键的4种方法总结

    本文主要介绍了Android中监听Home键的4种方法总结,主要讲解了onSaveInstanceState方法.onUserLeaveHint方法.ACTION_CLOSE_SYSTEM_DIALO ...

  8. Android增强现实(一)-AR的三种方式(展示篇)

    有一段时间没写博客了,事情比较多,博客进度有点跟不上了 1.Android增强现实(一)-AR的三种方式(展示篇) 2.Android增强现实(二)-支持拖拽控制进度和伸缩的VrGifView 3.A ...

  9. vue 函数 路由跳转_vue中通过路由跳转的三种方式

    router-view 实现路由内容的地方,引入组件时写到需要引入的地方 需要注意的是,使用vue-router控制路由则必须router-view作为容器. 通过路由跳转的三种方式 1.router ...

最新文章

  1. 第五次毕业设计任务书
  2. 销售订单行项目的装运点字段确认规则
  3. myeclipse设置注释格式
  4. 迫零响应法用于MIMO系统
  5. python 三维地球_用python生成地球运动的动态模拟动态图
  6. 作文 深海机器人_海底寻宝机器人
  7. DEDECMS 关键字不能小于2个字节!
  8. atitit.表格的绑定client side 最佳实践
  9. opengl双三次bezier曲面_OpenGL复杂物体建模
  10. [Redis] Redis实战
  11. 我去!三面字节跳动,竟次次败,带薪摸鱼偷刷阿里老哥的面试宝典,成功上岸!
  12. Processing 网格纹理制作(棋盘格)
  13. python glob.glob()
  14. 天津恒安标准人寿面试经验
  15. 洛谷 2448 无尽的生命
  16. 微信公众号文章爬取下载各种格式
  17. 关于nanopc debian系统的安装
  18. 制作PPT时怎样快捷修改默认字体?
  19. 武汉市2022年东湖高新区外资企业投资发展补贴政策申报指南
  20. uniapp的video组件视频预览略缩图问题

热门文章

  1. FPGA功耗那些事儿(转载)
  2. CnOpenData中国各行业工商注册企业分年份数量统计(含新增,注销企业数量)
  3. 金色新版萝卜影视系统源码+影视系统APP源码
  4. php执行who命令,Linux中的who命令实例介绍
  5. yolov5 代码内容解析
  6. html响应式布局ipad,响应式布局(Responsive design)
  7. Linux文本处理工具之cut命令
  8. Windows10系统自带的五笔输入法替换98字库
  9. iOS 苹果内购详细步骤
  10. echarts堆叠图显示总数 tooltips处理