Android中实现ImageView圆角化的几种 方式

您所在的位置:网站首页 java如何用图片设置按钮 Android中实现ImageView圆角化的几种 方式

Android中实现ImageView圆角化的几种 方式

2024-02-02 19:14| 来源: 网络整理| 查看: 265

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

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

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

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

这种方式比较简单直接。

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

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

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

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

public class RoundedImageView extends AppCompatImageView { // Constants for tile mode attributes private 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_CENTER setScaleType(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 deprecation super.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; } } @Override protected void drawableStateChanged() { super.drawableStateChanged(); invalidate(); } @Override public ScaleType getScaleType() { return mScaleType; } @Override public 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(); } } @Override public void setImageDrawable(Drawable drawable) { mResource = 0; mDrawable = RoundedDrawable.fromDrawable(drawable); updateDrawableAttrs(); super.setImageDrawable(mDrawable); } @Override public void setImageBitmap(Bitmap bm) { mResource = 0; mDrawable = RoundedDrawable.fromBitmap(bm); updateDrawableAttrs(); super.setImageDrawable(mDrawable); } @Override public 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); } @Override public void setBackground(Drawable background) { setBackgroundDrawable(background); } @Override public void setBackgroundResource(@DrawableRes int resId) { if (mBackgroundResource != resId) { mBackgroundResource = resId; mBackgroundDrawable = resolveBackgroundResource(); setBackgroundDrawable(mBackgroundDrawable); } } @Override public 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 attrs LayerDrawable ld = ((LayerDrawable) drawable); for (int i = 0, layers = ld.getNumberOfLayers(); i < layers; i++) { updateAttrs(ld.getDrawable(i), scaleType); } } } @Override @Deprecated public void setBackgroundDrawable(Drawable background) { mBackgroundDrawable = background; updateBackgroundDrawableAttrs(true); //noinspection deprecation super.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(); } @ColorInt public 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(); } }

使用方式直接在布局中:



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3