Android中实现ImageView圆角化的几种 方式
开发中我们经常在显示图片相关需求的时候需要加载圆角图片,下面几种方式来实现图片的圆角化。
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圆角化的几种 方式相关推荐
- android数据库侵入,Android中实现侵入式状态栏的两种方式
最近对"爸比讲故事"Android版本进行代码重构的时候,对之前版本的大部分界面的头部侵入式效果,作了一个总结和梳理,在期间查阅了thinkcool的博客和结合亲身实践,总结了2种 ...
- android的xml解析方式,Android中对xml文件解析的3种方式总结
前言 xml 是数据传输的一种格式,Android 中的布局文件.设置文件等都采用它来表示.Android 中对 xml 文件的解析也有多种方式,下面介绍常用的 3 种方式: Dom . SAX 和 ...
- android java调用_关于Android中Java调用外部命令的三种方式
此所谓三种方式,只是个人认为.本人还是菜鸟初涉,所以有所错误,请指正. 个人认为,Java调用外部命令.无非三种情况: 一.是只执行命令,不考虑返回值. 二.是执行命令的同时,还需要得到返回值. 三. ...
- android模拟按键方法,Android随笔之——模拟按键操作的几种方式
前几天转过一篇Android上模拟按键操作.触屏事件的博客,昨天又去找了百度.谷歌了一下,写了一点简单的测试代码,留待不时之需.有需要看之前转载的那篇博客的请看这里→_→转:Android随笔之--使 ...
- android中的ImageView,ImageView加载网络图片
android中的ImageView,ImageView加载网路图片 在布局文件中加入标签
- android启动其他app的服务器,Android中通过外部程序启动App的三种方法
这篇文章主要介绍了Android中通过外部程序启动App的三种方法, 本文讲解了直接通过包名. 通过自定义的Action. 通过Scheme三种方法,并分别给出操作代码,需要的朋友可以参考下 ==== ...
- Android中监听Home键的4种方法总结
本文主要介绍了Android中监听Home键的4种方法总结,主要讲解了onSaveInstanceState方法.onUserLeaveHint方法.ACTION_CLOSE_SYSTEM_DIALO ...
- Android增强现实(一)-AR的三种方式(展示篇)
有一段时间没写博客了,事情比较多,博客进度有点跟不上了 1.Android增强现实(一)-AR的三种方式(展示篇) 2.Android增强现实(二)-支持拖拽控制进度和伸缩的VrGifView 3.A ...
- vue 函数 路由跳转_vue中通过路由跳转的三种方式
router-view 实现路由内容的地方,引入组件时写到需要引入的地方 需要注意的是,使用vue-router控制路由则必须router-view作为容器. 通过路由跳转的三种方式 1.router ...
最新文章
- 第五次毕业设计任务书
- 销售订单行项目的装运点字段确认规则
- myeclipse设置注释格式
- 迫零响应法用于MIMO系统
- python 三维地球_用python生成地球运动的动态模拟动态图
- 作文 深海机器人_海底寻宝机器人
- DEDECMS 关键字不能小于2个字节!
- atitit.表格的绑定client side 最佳实践
- opengl双三次bezier曲面_OpenGL复杂物体建模
- [Redis] Redis实战
- 我去!三面字节跳动,竟次次败,带薪摸鱼偷刷阿里老哥的面试宝典,成功上岸!
- Processing 网格纹理制作(棋盘格)
- python glob.glob()
- 天津恒安标准人寿面试经验
- 洛谷 2448 无尽的生命
- 微信公众号文章爬取下载各种格式
- 关于nanopc debian系统的安装
- 制作PPT时怎样快捷修改默认字体?
- 武汉市2022年东湖高新区外资企业投资发展补贴政策申报指南
- uniapp的video组件视频预览略缩图问题